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


001:        /*
002:         * Copyright 2005-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.core.document;
017:
018:        import java.io.IOException;
019:        import java.io.StringReader;
020:        import java.util.LinkedHashMap;
021:        import java.util.Properties;
022:
023:        import javax.xml.parsers.DocumentBuilder;
024:        import javax.xml.parsers.DocumentBuilderFactory;
025:        import javax.xml.parsers.ParserConfigurationException;
026:
027:        import org.apache.commons.lang.StringUtils;
028:        import org.kuali.RiceConstants;
029:        import org.kuali.RiceKeyConstants;
030:        import org.kuali.core.bo.DocumentHeader;
031:        import org.kuali.core.bo.GlobalBusinessObject;
032:        import org.kuali.core.bo.PersistableBusinessObject;
033:        import org.kuali.core.exceptions.ValidationException;
034:        import org.kuali.core.maintenance.Maintainable;
035:        import org.kuali.core.rule.event.KualiDocumentEvent;
036:        import org.kuali.core.rule.event.SaveDocumentEvent;
037:        import org.kuali.core.util.GlobalVariables;
038:        import org.kuali.core.util.ObjectUtils;
039:        import org.kuali.core.util.UrlFactory;
040:        import org.kuali.core.workflow.service.KualiWorkflowDocument;
041:        import org.kuali.rice.KNSServiceLocator;
042:        import org.w3c.dom.Document;
043:        import org.w3c.dom.Node;
044:        import org.w3c.dom.NodeList;
045:        import org.xml.sax.InputSource;
046:        import org.xml.sax.SAXException;
047:
048:        import edu.iu.uis.eden.exception.WorkflowException;
049:
050:        /**
051:         * The maintenance xml structure will be: <maintainableDocumentContents maintainableImplClass="className">
052:         * <oldMaintainableObject>... </oldMaintainableObject> <newMaintainableObject>... </newMaintainableObject>
053:         * </maintainableDocumentContents> Maintenance Document
054:         */
055:        public final class MaintenanceDocumentBase extends DocumentBase
056:                implements  MaintenanceDocument {
057:            private static final long serialVersionUID = -505085142412593305L;
058:            private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger
059:                    .getLogger(MaintenanceDocumentBase.class);
060:            public static final String MAINTAINABLE_IMPL_CLASS = "maintainableImplClass";
061:            public static final String OLD_MAINTAINABLE_TAG_NAME = "oldMaintainableObject";
062:            public static final String NEW_MAINTAINABLE_TAG_NAME = "newMaintainableObject";
063:            public static final String MAINTENANCE_ACTION_TAG_NAME = "maintenanceAction";
064:
065:            protected Maintainable oldMaintainableObject;
066:            protected Maintainable newMaintainableObject;
067:            protected String xmlDocumentContents;
068:            protected boolean fieldsClearedOnCopy;
069:            protected boolean displayTopicFieldInNotes = false;
070:
071:            public MaintenanceDocumentBase() {
072:                super ();
073:                fieldsClearedOnCopy = false;
074:            }
075:
076:            /**
077:             * Initializies the maintainables.
078:             */
079:            public MaintenanceDocumentBase(String documentTypeName) {
080:                this ();
081:                Class clazz = KNSServiceLocator
082:                        .getMaintenanceDocumentDictionaryService()
083:                        .getMaintainableClass(documentTypeName);
084:                try {
085:                    oldMaintainableObject = (Maintainable) clazz.newInstance();
086:                    newMaintainableObject = (Maintainable) clazz.newInstance();
087:
088:                    // initialize maintainable with a business object
089:                    Class boClazz = KNSServiceLocator
090:                            .getMaintenanceDocumentDictionaryService()
091:                            .getBusinessObjectClass(documentTypeName);
092:                    oldMaintainableObject
093:                            .setBusinessObject((PersistableBusinessObject) boClazz
094:                                    .newInstance());
095:                    oldMaintainableObject.setBoClass(boClazz);
096:                    newMaintainableObject
097:                            .setBusinessObject((PersistableBusinessObject) boClazz
098:                                    .newInstance());
099:                    newMaintainableObject.setBoClass(boClazz);
100:                } catch (InstantiationException e) {
101:                    LOG.error("Unable to initialize maintainables of type "
102:                            + clazz.getName());
103:                    throw new RuntimeException(
104:                            "Unable to initialize maintainables of type "
105:                                    + clazz.getName());
106:                } catch (IllegalAccessException e) {
107:                    LOG.error("Unable to initialize maintainables of type "
108:                            + clazz.getName());
109:                    throw new RuntimeException(
110:                            "Unable to initialize maintainables of type "
111:                                    + clazz.getName());
112:                }
113:            }
114:
115:            /**
116:             * Builds out the document title for maintenance documents - this will get loaded into the flex doc and passed into workflow. It
117:             * will be searchable.
118:             */
119:            @Override
120:            public String getDocumentTitle() {
121:                String documentTitle = "";
122:
123:                documentTitle = newMaintainableObject.getDocumentTitle(this );
124:                if (StringUtils.isNotBlank(documentTitle)) {
125:                    // if doc title has been overridden by maintainable, use it
126:                    return documentTitle;
127:                }
128:
129:                // TODO - build out with bo label once we get the data dictionary stuff in place
130:                // build out the right classname
131:                String className = newMaintainableObject.getBusinessObject()
132:                        .getClass().getName();
133:                String truncatedClassName = className.substring(className
134:                        .lastIndexOf('.') + 1);
135:                if (isOldBusinessObjectInDocument()) {
136:                    documentTitle = "Edit ";
137:                } else {
138:                    documentTitle = "New ";
139:                }
140:                documentTitle += truncatedClassName + " - ";
141:                documentTitle += this .getDocumentHeader()
142:                        .getFinancialDocumentDescription()
143:                        + " ";
144:                // TODO: talk with Aaron about the getKeysName replacement
145:                // HashMap keyVals = (HashMap) newMaintainableObject.getKeysNameAndValuePairs();
146:                // Set list = keyVals.keySet();
147:                // Iterator i = list.iterator();
148:                // int idx = 0;
149:                // while(i.hasNext()) {
150:                // String key = (String) i.next();
151:                // String value = (String) keyVals.get(key);
152:                // if(idx != 0) {
153:                // documentTitle += ", ";
154:                // }
155:                // documentTitle += key;
156:                // documentTitle += " = ";
157:                // documentTitle += value;
158:                // idx++;
159:                // }
160:                // documentTitle += " - ";
161:                // documentTitle += this.getDocumentHeader().getDocumentDescription();
162:                return documentTitle;
163:            }
164:
165:            /**
166:             * @param xmlDocument
167:             * @return
168:             */
169:            private boolean isOldMaintainableInDocument(Document xmlDocument) {
170:                boolean isOldMaintainableInExistence = false;
171:                if (xmlDocument.getElementsByTagName(OLD_MAINTAINABLE_TAG_NAME)
172:                        .getLength() > 0) {
173:                    isOldMaintainableInExistence = true;
174:                }
175:                return isOldMaintainableInExistence;
176:            }
177:
178:            /**
179:             * Checks old maintainable bo has key values
180:             */
181:            public boolean isOldBusinessObjectInDocument() {
182:                boolean isOldBusinessObjectInExistence = false;
183:                if (oldMaintainableObject == null
184:                        || oldMaintainableObject.getBusinessObject() == null) {
185:                    isOldBusinessObjectInExistence = false;
186:                } else {
187:                    isOldBusinessObjectInExistence = KNSServiceLocator
188:                            .getPersistenceStructureService()
189:                            .hasPrimaryKeyFieldValues(
190:                                    oldMaintainableObject.getBusinessObject());
191:                }
192:                return isOldBusinessObjectInExistence;
193:            }
194:
195:            /**
196:             * This method is a simplified-naming wrapper around isOldBusinessObjectInDocument(), so that the method name matches the
197:             * functionality.
198:             */
199:            public boolean isNew() {
200:                if (RiceConstants.MAINTENANCE_EDIT_ACTION
201:                        .equalsIgnoreCase(newMaintainableObject
202:                                .getMaintenanceAction())) {
203:                    return false;
204:                } else if (RiceConstants.MAINTENANCE_NEWWITHEXISTING_ACTION
205:                        .equalsIgnoreCase(newMaintainableObject
206:                                .getMaintenanceAction())) {
207:                    return false;
208:                } else if (RiceConstants.MAINTENANCE_NEW_ACTION
209:                        .equalsIgnoreCase(newMaintainableObject
210:                                .getMaintenanceAction())) {
211:                    return true;
212:                } else if (RiceConstants.MAINTENANCE_COPY_ACTION
213:                        .equalsIgnoreCase(newMaintainableObject
214:                                .getMaintenanceAction())) {
215:                    return true;
216:                } else {
217:                    return true;
218:                }
219:                // return !isOldBusinessObjectInDocument();
220:            }
221:
222:            /**
223:             * This method is a simplified-naming wrapper around isOldBusinessObjectInDocument(), so that the method name matches the
224:             * functionality.
225:             */
226:            public boolean isEdit() {
227:                if (RiceConstants.MAINTENANCE_EDIT_ACTION
228:                        .equalsIgnoreCase(newMaintainableObject
229:                                .getMaintenanceAction())) {
230:                    return true;
231:                } else {
232:                    return false;
233:                }
234:                // return isOldBusinessObjectInDocument();
235:            }
236:
237:            public boolean isNewWithExisting() {
238:                if (RiceConstants.MAINTENANCE_NEWWITHEXISTING_ACTION
239:                        .equalsIgnoreCase(newMaintainableObject
240:                                .getMaintenanceAction())) {
241:                    return true;
242:                } else {
243:                    return false;
244:                }
245:            }
246:
247:            public void populateMaintainablesFromXmlDocumentContents() {
248:                // get a hold of the parsed xml document, then read the classname,
249:                // then instantiate one to two instances depending on content
250:                // then populate those instances
251:                if (!StringUtils.isEmpty(xmlDocumentContents)) {
252:                    DocumentBuilderFactory factory = DocumentBuilderFactory
253:                            .newInstance();
254:
255:                    try {
256:                        DocumentBuilder builder = factory.newDocumentBuilder();
257:                        Document xmlDocument = builder.parse(new InputSource(
258:                                new StringReader(xmlDocumentContents)));
259:                        String clazz = xmlDocument.getDocumentElement()
260:                                .getAttribute(MAINTAINABLE_IMPL_CLASS);
261:                        if (isOldMaintainableInDocument(xmlDocument)) {
262:                            oldMaintainableObject = (Maintainable) Class
263:                                    .forName(clazz).newInstance();
264:                            PersistableBusinessObject bo = getBusinessObjectFromXML(OLD_MAINTAINABLE_TAG_NAME);
265:
266:                            String oldMaintenanceAction = getMaintenanceAction(
267:                                    xmlDocument, OLD_MAINTAINABLE_TAG_NAME);
268:                            oldMaintainableObject
269:                                    .setMaintenanceAction(oldMaintenanceAction);
270:
271:                            oldMaintainableObject.setBusinessObject(bo);
272:                            oldMaintainableObject.setBoClass(bo.getClass());
273:                        }
274:                        newMaintainableObject = (Maintainable) Class.forName(
275:                                clazz).newInstance();
276:                        PersistableBusinessObject bo = getBusinessObjectFromXML(NEW_MAINTAINABLE_TAG_NAME);
277:                        newMaintainableObject.setBusinessObject(bo);
278:                        newMaintainableObject.setBoClass(bo.getClass());
279:
280:                        String newMaintenanceAction = getMaintenanceAction(
281:                                xmlDocument, NEW_MAINTAINABLE_TAG_NAME);
282:                        newMaintainableObject
283:                                .setMaintenanceAction(newMaintenanceAction);
284:
285:                    } catch (ParserConfigurationException e) {
286:                        LOG.error("Error while parsing document contents", e);
287:                        throw new RuntimeException(
288:                                "Could not load document contents from xml", e);
289:                    } catch (SAXException e) {
290:                        LOG.error("Error while parsing document contents", e);
291:                        throw new RuntimeException(
292:                                "Could not load document contents from xml", e);
293:                    } catch (IOException e) {
294:                        LOG.error("Error while parsing document contents", e);
295:                        throw new RuntimeException(
296:                                "Could not load document contents from xml", e);
297:                    } catch (InstantiationException e) {
298:                        LOG.error("Error while parsing document contents", e);
299:                        throw new RuntimeException(
300:                                "Could not load document contents from xml", e);
301:                    } catch (IllegalAccessException e) {
302:                        LOG.error("Error while parsing document contents", e);
303:                        throw new RuntimeException(
304:                                "Could not load document contents from xml", e);
305:                    } catch (ClassNotFoundException e) {
306:                        LOG.error("Error while parsing document contents", e);
307:                        throw new RuntimeException(
308:                                "Could not load document contents from xml", e);
309:                    }
310:
311:                }
312:            }
313:
314:            /**
315:             * This method is a lame containment of ugly DOM walking code. This is ONLY necessary because of the version conflicts between
316:             * Xalan.jar in 2.6.x and 2.7. As soon as we can upgrade to 2.7, this will be switched to using XPath, which is faster and much
317:             * easier on the eyes.
318:             *
319:             * @param xmlDocument
320:             * @param oldOrNewElementName - String oldMaintainableObject or newMaintainableObject
321:             * @return the value of the element, or null if none was there
322:             */
323:            private String getMaintenanceAction(Document xmlDocument,
324:                    String oldOrNewElementName) {
325:
326:                if (StringUtils.isBlank(oldOrNewElementName)) {
327:                    throw new IllegalArgumentException(
328:                            "oldOrNewElementName may not be blank, null, or empty-string.");
329:                }
330:
331:                String maintenanceAction = null;
332:                NodeList rootChildren = xmlDocument.getDocumentElement()
333:                        .getChildNodes();
334:                for (int i = 0; i < rootChildren.getLength(); i++) {
335:                    Node rootChild = rootChildren.item(i);
336:                    if (oldOrNewElementName.equalsIgnoreCase(rootChild
337:                            .getNodeName())) {
338:                        NodeList maintChildren = rootChild.getChildNodes();
339:                        for (int j = 0; j < maintChildren.getLength(); j++) {
340:                            Node maintChild = maintChildren.item(j);
341:                            if (MAINTENANCE_ACTION_TAG_NAME
342:                                    .equalsIgnoreCase(maintChild.getNodeName())) {
343:                                maintenanceAction = maintChild.getChildNodes()
344:                                        .item(0).getNodeValue();
345:                            }
346:                        }
347:                    }
348:                }
349:                return maintenanceAction;
350:            }
351:
352:            /**
353:             * Retrieves substring of document contents from maintainable tag name. Then use xml service to translate xml into a business
354:             * object.
355:             */
356:            private PersistableBusinessObject getBusinessObjectFromXML(
357:                    String maintainableTagName) {
358:                String maintXml = StringUtils.substringBetween(
359:                        xmlDocumentContents, "<" + maintainableTagName + ">",
360:                        "</" + maintainableTagName + ">");
361:                PersistableBusinessObject businessObject = (PersistableBusinessObject) KNSServiceLocator
362:                        .getXmlObjectSerializerService().fromXml(maintXml);
363:                return businessObject;
364:            }
365:
366:            /**
367:             * Populates the xml document contents from the maintainables.
368:             *
369:             * @see org.kuali.core.document.MaintenanceDocument#populateXmlDocumentContentsFromMaintainables()
370:             */
371:            public void populateXmlDocumentContentsFromMaintainables() {
372:                StringBuffer docContentBuffer = new StringBuffer();
373:                docContentBuffer
374:                        .append(
375:                                "<maintainableDocumentContents maintainableImplClass=\"")
376:                        .append(newMaintainableObject.getClass().getName())
377:                        .append("\">");
378:                if (oldMaintainableObject != null
379:                        && oldMaintainableObject.getBusinessObject() != null) {
380:                    // TODO: refactor this out into a method
381:                    docContentBuffer.append("<" + OLD_MAINTAINABLE_TAG_NAME
382:                            + ">");
383:
384:                    PersistableBusinessObject oldBo = oldMaintainableObject
385:                            .getBusinessObject();
386:                    ObjectUtils.materializeAllSubObjects(oldBo); // hack to resolve XStream not dealing well with Proxies
387:                    docContentBuffer.append(KNSServiceLocator
388:                            .getXmlObjectSerializerService().toXml(oldBo));
389:
390:                    // add the maintainable's maintenanceAction
391:                    docContentBuffer.append("<" + MAINTENANCE_ACTION_TAG_NAME
392:                            + ">");
393:                    docContentBuffer.append(oldMaintainableObject
394:                            .getMaintenanceAction());
395:                    docContentBuffer.append("</" + MAINTENANCE_ACTION_TAG_NAME
396:                            + ">\n");
397:
398:                    docContentBuffer.append("</" + OLD_MAINTAINABLE_TAG_NAME
399:                            + ">");
400:                }
401:                docContentBuffer.append("<" + NEW_MAINTAINABLE_TAG_NAME + ">");
402:
403:                PersistableBusinessObject newBo = newMaintainableObject
404:                        .getBusinessObject();
405:                ObjectUtils.materializeAllSubObjects(newBo); // hack to resolve XStream not dealing well with Proxies
406:                docContentBuffer.append(KNSServiceLocator
407:                        .getXmlObjectSerializerService().toXml(newBo));
408:
409:                // add the maintainable's maintenanceAction
410:                docContentBuffer
411:                        .append("<" + MAINTENANCE_ACTION_TAG_NAME + ">");
412:                docContentBuffer.append(newMaintainableObject
413:                        .getMaintenanceAction());
414:                docContentBuffer.append("</" + MAINTENANCE_ACTION_TAG_NAME
415:                        + ">\n");
416:
417:                docContentBuffer.append("</" + NEW_MAINTAINABLE_TAG_NAME + ">");
418:                docContentBuffer.append("</maintainableDocumentContents>");
419:                xmlDocumentContents = docContentBuffer.toString();
420:            }
421:
422:            /**
423:             * @see org.kuali.core.document.DocumentBase#handleRouteStatusChange()
424:             */
425:            @Override
426:            public void handleRouteStatusChange() {
427:                super .handleRouteStatusChange();
428:
429:                KualiWorkflowDocument workflowDocument = getDocumentHeader()
430:                        .getWorkflowDocument();
431:                getNewMaintainableObject().handleRouteStatusChange(
432:                        getDocumentHeader());
433:                // commit the changes to the Maintainable BusinessObject when it goes to Processed (ie, fully approved),
434:                // and also unlock it
435:                if (workflowDocument.stateIsProcessed()) {
436:                    String documentNumber = getDocumentHeader()
437:                            .getDocumentNumber();
438:                    newMaintainableObject.setDocumentNumber(documentNumber);
439:                    newMaintainableObject.saveBusinessObject();
440:                    KNSServiceLocator.getMaintenanceDocumentService()
441:                            .deleteLocks(documentNumber);
442:                }
443:
444:                // unlock the document when its canceled or disapproved
445:                if (workflowDocument.stateIsCanceled()
446:                        || workflowDocument.stateIsDisapproved()) {
447:                    String documentNumber = getDocumentHeader()
448:                            .getDocumentNumber();
449:                    KNSServiceLocator.getMaintenanceDocumentService()
450:                            .deleteLocks(documentNumber);
451:                }
452:            }
453:
454:            /**
455:             * Pre-Save hook.
456:             *
457:             * @see org.kuali.core.document.Document#prepareForSave()
458:             */
459:            @Override
460:            public void prepareForSave() {
461:                if (newMaintainableObject != null) {
462:                    newMaintainableObject.prepareForSave();
463:                }
464:            }
465:
466:            /**
467:             * @see org.kuali.core.document.DocumentBase#processAfterRetrieve()
468:             */
469:            @Override
470:            public void processAfterRetrieve() {
471:                super .processAfterRetrieve();
472:                populateMaintainablesFromXmlDocumentContents();
473:                if (newMaintainableObject != null) {
474:                    newMaintainableObject.processAfterRetrieve();
475:                }
476:            }
477:
478:            /**
479:             * @return Returns the newMaintainableObject.
480:             */
481:            public Maintainable getNewMaintainableObject() {
482:                return newMaintainableObject;
483:            }
484:
485:            /**
486:             * @param newMaintainableObject The newMaintainableObject to set.
487:             */
488:            public void setNewMaintainableObject(
489:                    Maintainable newMaintainableObject) {
490:                this .newMaintainableObject = newMaintainableObject;
491:            }
492:
493:            /**
494:             * @return Returns the oldMaintainableObject.
495:             */
496:            public Maintainable getOldMaintainableObject() {
497:                return oldMaintainableObject;
498:            }
499:
500:            /**
501:             * @param oldMaintainableObject The oldMaintainableObject to set.
502:             */
503:            public void setOldMaintainableObject(
504:                    Maintainable oldMaintainableObject) {
505:                this .oldMaintainableObject = oldMaintainableObject;
506:            }
507:
508:            @Override
509:            public void setDocumentNumber(String documentNumber) {
510:                super .setDocumentNumber(documentNumber);
511:
512:                // set the finDocNumber on the Maintainable
513:                oldMaintainableObject.setDocumentNumber(documentNumber);
514:                newMaintainableObject.setDocumentNumber(documentNumber);
515:
516:            }
517:
518:            /**
519:             * Gets the fieldsClearedOnCopy attribute.
520:             *
521:             * @return Returns the fieldsClearedOnCopy.
522:             */
523:            public final boolean isFieldsClearedOnCopy() {
524:                return fieldsClearedOnCopy;
525:            }
526:
527:            /**
528:             * Sets the fieldsClearedOnCopy attribute value.
529:             *
530:             * @param fieldsClearedOnCopy The fieldsClearedOnCopy to set.
531:             */
532:            public final void setFieldsClearedOnCopy(boolean fieldsClearedOnCopy) {
533:                this .fieldsClearedOnCopy = fieldsClearedOnCopy;
534:            }
535:
536:            /**
537:             * @see org.kuali.core.bo.BusinessObjectBase#toStringMapper()
538:             */
539:            @Override
540:            protected LinkedHashMap toStringMapper() {
541:                LinkedHashMap m = new LinkedHashMap();
542:
543:                m.put("versionNumber", getVersionNumber());
544:                m.put("comp", Boolean.valueOf(getDocumentHeader()
545:                        .getWorkflowDocument().isCompletionRequested()));
546:                m.put("app", Boolean.valueOf(getDocumentHeader()
547:                        .getWorkflowDocument().isApprovalRequested()));
548:                m.put("ack", Boolean.valueOf(getDocumentHeader()
549:                        .getWorkflowDocument().isAcknowledgeRequested()));
550:                m.put("fyi", Boolean.valueOf(getDocumentHeader()
551:                        .getWorkflowDocument().isFYIRequested()));
552:
553:                return m;
554:            }
555:
556:            /**
557:             * Gets the xmlDocumentContents attribute.
558:             *
559:             * @return Returns the xmlDocumentContents.
560:             */
561:            public String getXmlDocumentContents() {
562:                return xmlDocumentContents;
563:            }
564:
565:            /**
566:             * Sets the xmlDocumentContents attribute value.
567:             *
568:             * @param xmlDocumentContents The xmlDocumentContents to set.
569:             */
570:            public void setXmlDocumentContents(String xmlDocumentContents) {
571:                this .xmlDocumentContents = xmlDocumentContents;
572:            }
573:
574:            /**
575:             * @see org.kuali.core.document.Document#getAllowsCopy()
576:             */
577:            public boolean getAllowsCopy() {
578:                Boolean allowsCopy = KNSServiceLocator
579:                        .getMaintenanceDocumentDictionaryService()
580:                        .getAllowsCopy(this );
581:                if (allowsCopy != null) {
582:                    return allowsCopy.booleanValue();
583:                } else {
584:                    return false;
585:                }
586:            }
587:
588:            /**
589:             * @see org.kuali.core.document.MaintenanceDocument#getDisplayTopicFieldInNotes()
590:             */
591:            public boolean getDisplayTopicFieldInNotes() {
592:                return displayTopicFieldInNotes;
593:            }
594:
595:            /**
596:             * @see org.kuali.core.document.MaintenanceDocument#setDisplayTopicFieldInNotes(boolean)
597:             */
598:            public void setDisplayTopicFieldInNotes(
599:                    boolean displayTopicFieldInNotes) {
600:                this .displayTopicFieldInNotes = displayTopicFieldInNotes;
601:            }
602:
603:            @Override
604:            /**
605:             * Overridden to avoid serializing the xml twice, because of the xmlDocumentContents property of this object
606:             */
607:            public String serializeDocumentToXml() {
608:                String tempXmlDocumentContents = xmlDocumentContents;
609:                xmlDocumentContents = null;
610:                String xmlForWorkflow = super .serializeDocumentToXml();
611:                xmlDocumentContents = tempXmlDocumentContents;
612:                return xmlForWorkflow;
613:            }
614:
615:            @Override
616:            public void prepareForSave(KualiDocumentEvent event) {
617:                super .prepareForSave(event);
618:                populateXmlDocumentContentsFromMaintainables();
619:            }
620:
621:            /**
622:             * Explicitly NOT calling super here.  This is a complete override of the validation 
623:             * rules behavior.
624:             * 
625:             * @see org.kuali.core.document.DocumentBase#validateBusinessRules(org.kuali.core.rule.event.KualiDocumentEvent)
626:             */
627:            public void validateBusinessRules(KualiDocumentEvent event) {
628:                if (!GlobalVariables.getErrorMap().isEmpty()) {
629:                    logErrors();
630:                    throw new ValidationException(
631:                            "errors occured before business rule");
632:                }
633:
634:                // check for locking documents for MaintenanceDocuments
635:                if (this  instanceof  MaintenanceDocument) {
636:                    checkForLockingDocument();
637:                }
638:
639:                // perform validation against rules engine
640:                LOG.info("invoking rules engine on document "
641:                        + getDocumentNumber());
642:                boolean isValid = true;
643:                isValid = KNSServiceLocator.getKualiRuleService().applyRules(
644:                        event);
645:
646:                // check to see if the br eval passed or failed
647:                if (!isValid) {
648:                    logErrors();
649:                    // TODO: better error handling at the lower level and a better error message are
650:                    // needed here
651:                    throw new ValidationException(
652:                            "business rule evaluation failed");
653:                } else if (!GlobalVariables.getErrorMap().isEmpty()) {
654:                    logErrors();
655:                    if (event instanceof  SaveDocumentEvent) {
656:                        // for maintenance documents, we want to always actually do a save if the
657:                        // user requests a save, even if there are validation or business rules
658:                        // failures. this empty if does this, and allows the document to be saved,
659:                        // even if there are failures.
660:                        // BR or validation failures on a ROUTE even should always stop the route,
661:                        // that has not changed
662:                    } else {
663:                        throw new ValidationException(
664:                                "Unreported errors occured during business rule evaluation (rule developer needs to put meaningful error messages into global ErrorMap)");
665:                    }
666:                }
667:                LOG.debug("validation completed");
668:
669:            }
670:
671:            private void checkForLockingDocument() {
672:
673:                LOG.info("starting checkForLockingDocument");
674:
675:                // get the docHeaderId of the blocking docs, if any are locked and blocking
676:                String blockingDocId = KNSServiceLocator
677:                        .getMaintenanceDocumentService().getLockingDocumentId(
678:                                this );
679:
680:                // if we got nothing, then no docs are blocking, and we're done
681:                if (StringUtils.isBlank(blockingDocId)) {
682:                    return;
683:                }
684:
685:                LOG.info("Locking document found:  docId = " + blockingDocId
686:                        + ".");
687:
688:                // load the blocking locked document
689:                org.kuali.core.document.Document lockedDocument;
690:                try {
691:                    lockedDocument = KNSServiceLocator.getDocumentService()
692:                            .getByDocumentHeaderId(blockingDocId);
693:                } catch (WorkflowException e) {
694:                    throw new ValidationException(
695:                            "Could not load the locking document.", e);
696:                }
697:
698:                // if we can ignore the lock (see method notes), then exit cause we're done
699:                if (lockCanBeIgnored(lockedDocument)) {
700:                    return;
701:                }
702:
703:                // build the link URL for the blocking document
704:                Properties parameters = new Properties();
705:                parameters.put(RiceConstants.DISPATCH_REQUEST_PARAMETER,
706:                        RiceConstants.DOC_HANDLER_METHOD);
707:                parameters.put(RiceConstants.PARAMETER_DOC_ID, blockingDocId);
708:                parameters.put(RiceConstants.PARAMETER_COMMAND,
709:                        RiceConstants.METHOD_DISPLAY_DOC_SEARCH_VIEW);
710:                String blockingUrl = UrlFactory.parameterizeUrl(
711:                        RiceConstants.MAINTENANCE_ACTION, parameters);
712:                LOG.debug("blockingUrl = '" + blockingUrl + "'");
713:
714:                // post an error about the locked document
715:                LOG.debug("Maintenance record: "
716:                        + lockedDocument.getDocumentHeader()
717:                                .getDocumentNumber() + "is locked.");
718:                String[] errorParameters = { blockingUrl, blockingDocId };
719:                GlobalVariables.getErrorMap().putError(
720:                        RiceConstants.GLOBAL_ERRORS,
721:                        RiceKeyConstants.ERROR_MAINTENANCE_LOCKED,
722:                        errorParameters);
723:
724:                throw new ValidationException(
725:                        "Maintenance Record is locked by another document.");
726:            }
727:
728:            /**
729:             * This method guesses whether the current user should be allowed to change a document even though it is locked. It probably
730:             * should use Authorization instead? See KULNRVSYS-948
731:             * 
732:             * @param lockedDocument
733:             * @return
734:             * @throws WorkflowException
735:             */
736:            private boolean lockCanBeIgnored(
737:                    org.kuali.core.document.Document lockedDocument) {
738:                // TODO: implement real authorization for Maintenance Document Save/Route - KULNRVSYS-948
739:
740:                DocumentHeader documentHeader = lockedDocument
741:                        .getDocumentHeader();
742:
743:                // get the user-id. if no user-id, then we can do this test, so exit
744:                String userId = GlobalVariables.getUserSession().getNetworkId()
745:                        .trim();
746:                if (StringUtils.isBlank(userId)) {
747:                    return false; // dont bypass locking
748:                }
749:
750:                // if the current user is not the initiator of the blocking document
751:                if (!userId.equalsIgnoreCase(documentHeader
752:                        .getWorkflowDocument().getInitiatorNetworkId().trim())) {
753:                    return false;
754:                }
755:
756:                // if the blocking document hasn't been routed, we can ignore it
757:                return RiceConstants.DocumentStatusCodes.INITIATED
758:                        .equals(documentHeader.getFinancialDocumentStatusCode());
759:            }
760:
761:            /**
762:             * this needs to happen after the document itself is saved, to preserve consistency of the ver_nbr and in the case of initial
763:             * save, because this can't be saved until the document is saved initially
764:             * 
765:             * @see org.kuali.core.document.DocumentBase#postProcessSave(org.kuali.core.rule.event.KualiDocumentEvent)
766:             */
767:            @Override
768:            public void postProcessSave(KualiDocumentEvent event) {
769:                PersistableBusinessObject bo = getNewMaintainableObject()
770:                        .getBusinessObject();
771:                if (bo instanceof  GlobalBusinessObject) {
772:                    KNSServiceLocator.getBusinessObjectService().save(bo);
773:                }
774:                //currently only global documents could change the list of what they're affecting during routing,
775:                //so could restrict this to only happening with them, but who knows if that will change, so safest
776:                //to always do the delete and re-add...seems a bit inefficient though if nothing has changed, which is
777:                //most of the time...could also try to only add/update/delete what's changed, but this is easier
778:                if (!(event instanceof  SaveDocumentEvent)) { //don't lock until they route
779:                    KNSServiceLocator.getMaintenanceDocumentService()
780:                            .deleteLocks(this .getDocumentNumber());
781:                    KNSServiceLocator.getMaintenanceDocumentService()
782:                            .storeLocks(
783:                                    this .getNewMaintainableObject()
784:                                            .generateMaintenanceLocks());
785:                }
786:            }
787:
788:            /**
789:             * @see org.kuali.core.document.DocumentBase#getDocumentBusinessObject()
790:             */
791:            @Override
792:            public PersistableBusinessObject getDocumentBusinessObject() {
793:                if (documentBusinessObject == null) {
794:                    documentBusinessObject = this.newMaintainableObject
795:                            .getBusinessObject();
796:                }
797:                return documentBusinessObject;
798:            }
799:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.