001: /*
002: *
003: * Copyright (c) 2004 SourceTap - www.sourcetap.com
004: *
005: * The contents of this file are subject to the SourceTap Public License
006: * ("License"); You may not use this file except in compliance with the
007: * License. You may obtain a copy of the License at http://www.sourcetap.com/license.htm
008: * Software distributed under the License is distributed on an "AS IS" basis,
009: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
010: * the specific language governing rights and limitations under the License.
011: *
012: * The above copyright notice and this permission notice shall be included
013: * in all copies or substantial portions of the Software.
014: *
015: */
016:
017: package com.sourcetap.sfa.event;
018:
019: import java.util.ArrayList;
020: import java.util.Arrays;
021: import java.util.Enumeration;
022: import java.util.HashMap;
023: import java.util.Iterator;
024: import java.util.LinkedList;
025: import java.util.List;
026: import java.util.Map;
027: import java.util.Vector;
028:
029: import javax.servlet.http.HttpServletRequest;
030:
031: import org.ofbiz.base.util.Debug;
032: import org.ofbiz.base.util.UtilTimer;
033: import org.ofbiz.entity.GenericDelegator;
034: import org.ofbiz.entity.GenericEntityException;
035: import org.ofbiz.entity.GenericPK;
036: import org.ofbiz.entity.GenericValue;
037: import org.ofbiz.entity.condition.EntityComparisonOperator;
038:
039: import com.sourcetap.sfa.ui.UIDisplayObject;
040: import com.sourcetap.sfa.ui.UIFieldInfo;
041: import com.sourcetap.sfa.ui.UIScreenSection;
042: import com.sourcetap.sfa.ui.UIScreenSectionEntity;
043: import com.sourcetap.sfa.ui.UIWebUtility;
044: import com.sourcetap.sfa.util.DelimitedPairDecoder;
045: import com.sourcetap.sfa.util.DelimitedValueDecoder;
046: import com.sourcetap.sfa.util.QueryInfo;
047: import com.sourcetap.sfa.util.StringHelper;
048: import com.sourcetap.sfa.util.UserInfo;
049:
050: /**
051: * DOCUMENT ME!
052: *
053: */
054: public class DataMatrix {
055: public static final String module = DataMatrix.class.getName();
056: private static final boolean TIMER = false;
057: protected DataBuffer currentBuffer = null;
058: protected DataBuffer originalBuffer = null;
059: protected ArrayList deleteFlags = new ArrayList();
060: protected Vector entityParamVector = null;
061: protected GenericDelegator delegator = null;
062: protected int rowCount = 0;
063:
064: public DataMatrix(GenericDelegator delegator,
065: Vector entityParamVector) {
066: setDelegator(delegator);
067: currentBuffer = new DataBuffer(delegator, this );
068: originalBuffer = new DataBuffer(delegator, this );
069: setEntityParamVector(entityParamVector);
070: }
071:
072: /**
073: * DOCUMENT ME!
074: *
075: * @return
076: */
077: public DataBuffer getCurrentBuffer() {
078: return currentBuffer;
079: }
080:
081: /**
082: * DOCUMENT ME!
083: *
084: * @return
085: */
086: public DataBuffer getOriginalBuffer() {
087: return originalBuffer;
088: }
089:
090: /**
091: * DOCUMENT ME!
092: *
093: * @param isDeleted
094: */
095: public void addDeleteFlag(boolean isDeleted) {
096: deleteFlags.add(new Boolean(isDeleted));
097: }
098:
099: /**
100: * DOCUMENT ME!
101: *
102: * @return
103: */
104: public Vector getEntityParamVector() {
105: return entityParamVector;
106: }
107:
108: /**
109: * DOCUMENT ME!
110: *
111: * @param entityParamVector_
112: */
113: public void setEntityParamVector(Vector entityParamVector_) {
114: entityParamVector = entityParamVector_;
115: }
116:
117: /**
118: * DOCUMENT ME!
119: *
120: * @param entityName
121: * @param hasSequenceKey
122: * @param isUpdateable
123: */
124: public void addEntity(String entityName, boolean hasSequenceKey,
125: boolean isUpdateable) {
126: // Vector attributeVector = new Vector();
127: // for (int attributeNbr = 0; attributeNbr < uiEntity.getUiAttributeList().size(); attributeNbr++) {
128: // String attributeName = uiEntity.getUiAttribute(attributeNbr).getAttributeName();
129: // attributeVector.add(attributeName);
130: // }
131: HashMap parameterMap = new HashMap();
132: parameterMap.put("entityName", entityName);
133: parameterMap.put("attributeVector", new Vector());
134: parameterMap.put("hasSequenceKey", new Boolean(hasSequenceKey));
135: parameterMap.put("isUpdateable", new Boolean(isUpdateable));
136:
137: Debug.logVerbose("[DataMatrix.addEntity] parameterMap: "
138: + parameterMap.toString(), module);
139:
140: Debug.logVerbose("[DataMatrix.addEntity] entityParamVector: "
141: + entityParamVector.toString(), module);
142:
143: getEntityParamVector().add(parameterMap);
144: }
145:
146: /**
147: * DOCUMENT ME!
148: *
149: * @param entityNbr
150: *
151: * @return
152: */
153: public String getEntityName(int entityNbr) {
154: HashMap parameterMap = (HashMap) getEntityParamVector().get(
155: entityNbr);
156: String entityName = (String) parameterMap.get("entityName");
157:
158: return entityName;
159: }
160:
161: /**
162: * DOCUMENT ME!
163: *
164: * @param entityNbr
165: *
166: * @return
167: */
168: public boolean getHasSequenceKey(int entityNbr) {
169: HashMap parameterMap = (HashMap) getEntityParamVector().get(
170: entityNbr);
171: Boolean hasSequenceKey = (Boolean) parameterMap
172: .get("hasSequenceKey");
173:
174: return hasSequenceKey.booleanValue();
175: }
176:
177: /**
178: * DOCUMENT ME!
179: *
180: * @param entityNbr
181: *
182: * @return
183: */
184: public boolean getIsUpdateable(int entityNbr) {
185:
186: HashMap parameterMap = (HashMap) getEntityParamVector().get(
187: entityNbr);
188: Boolean isUpdateable = (Boolean) parameterMap
189: .get("isUpdateable");
190:
191: return isUpdateable.booleanValue();
192: }
193:
194: /**
195: * DOCUMENT ME!
196: *
197: * @param entityNbr
198: *
199: * @return
200: */
201: public Vector getAttributeVector(int entityNbr) {
202: HashMap parameterMap = (HashMap) getEntityParamVector().get(
203: entityNbr);
204: Vector attributeVector = (Vector) parameterMap
205: .get("attributeVector");
206:
207: return attributeVector;
208: }
209:
210: /**
211: * DOCUMENT ME!
212: *
213: * @param entityNbr
214: * @param attributeNbr
215: *
216: * @return
217: */
218: public String getAttributeName(int entityNbr, int attributeNbr) {
219: HashMap parameterMap = (HashMap) getEntityParamVector().get(
220: entityNbr);
221: Vector attributeVector = (Vector) parameterMap
222: .get("attributeVector");
223: String attributeName = (String) attributeVector
224: .get(attributeNbr);
225:
226: return attributeName;
227: }
228:
229: /**
230: * DOCUMENT ME!
231: *
232: * @return
233: */
234: public Vector getEntityNameVector() {
235: Vector entityNameVector = new Vector();
236:
237: for (int entityNbr = 0; entityNbr < getEntityParamVector()
238: .size(); entityNbr++) {
239: entityNameVector.add(getEntityName(entityNbr));
240: }
241:
242: return entityNameVector;
243: }
244:
245: /**
246: * DOCUMENT ME!
247: *
248: * @return
249: */
250: public GenericDelegator getDelegator() {
251: return delegator;
252: }
253:
254: /**
255: * DOCUMENT ME!
256: *
257: * @param delegator_
258: */
259: public void setDelegator(GenericDelegator delegator_) {
260: delegator = delegator_;
261: }
262:
263: /**
264: * DOCUMENT ME!
265: *
266: * @return
267: */
268: public int getRowCount() {
269: return rowCount;
270: }
271:
272: /**
273: * DOCUMENT ME!
274: *
275: * @param rowCount_
276: */
277: public void setRowCount(int rowCount_) {
278: rowCount = rowCount_;
279: }
280:
281: //-------------------------------------------------------------------------
282: // Put values from the screen into the value matrix
283: //-------------------------------------------------------------------------
284: public int fillFromHtml(HttpServletRequest request,
285: UIScreenSection uiScreenSection)
286: throws GenericEntityException {
287:
288: UtilTimer utilTimer = new UtilTimer();
289:
290: if (TIMER) {
291: utilTimer.timerString(3, "[DataMatrix.fillFromHTML] Start");
292: }
293:
294: // Get the row count.
295: if (request.getParameter("rowCount") == null) {
296: throw new GenericEntityException(
297: "rowCount parameter not found in request object.");
298: }
299:
300: if (request.getParameter("rowCount").equals("")) {
301: throw new GenericEntityException(
302: "rowCount parameter is empty in request object.");
303: }
304:
305: try {
306: setRowCount(Integer.valueOf(
307: request.getParameter("rowCount")).intValue());
308: } catch (NumberFormatException e) {
309: throw new GenericEntityException(
310: "rowCount parameter in request object does not contain a number.");
311: }
312:
313: for (int row = 0; row < getRowCount(); row++) {
314: // Create an array list of empty generic values to hold the values from the screen for one row.
315: addRowFromHTML(row, request, uiScreenSection);
316: }
317:
318: if (TIMER) {
319: utilTimer.timerString(3, "[DataMatrix.fillFromHTML] End");
320: }
321:
322: return getRowCount();
323: }
324:
325: /**
326: * DOCUMENT ME!
327: *
328: * @param row
329: * @param request
330: * @param uiScreenSection
331: *
332: * @throws GenericEntityException
333: */
334: public void addRowFromHTML(int row, HttpServletRequest request,
335: UIScreenSection uiScreenSection)
336: throws GenericEntityException {
337: UtilTimer utilTimer = new UtilTimer();
338:
339: if (TIMER) {
340: utilTimer.timerString(4,
341: "[DataMatrix.addRowFromHTML] Start");
342: }
343:
344: // Create an empty row to be updated and stored in the current and original buffers.
345: Vector currentRow = getCurrentBuffer().createEmptyRow();
346:
347: // Vector originalRow = (Vector)currentRow.clone(); -- This didn't really create a new object. It caused
348: // all operations on originalRow to be done on the currentRow also.
349: Vector originalRow = getOriginalBuffer().createEmptyRow();
350:
351: // Loop through the entities and attributes for the current screen section, and get the value
352: // from the request object for each one, and store it in the contents.
353: for (int entityNbr = 0; entityNbr < getEntityParamVector()
354: .size(); entityNbr++) {
355: String entityName = getEntityName(entityNbr);
356:
357: if (TIMER) {
358: utilTimer.timerString(4,
359: "[DataMatrix.addRowFromHTML] Start processing entity "
360: + String.valueOf(entityNbr) + " ("
361: + entityName + ")");
362: }
363:
364: // Get references to the orginal and current generic values for this entity.
365: GenericValue currentGV = (GenericValue) (currentRow
366: .get(entityNbr));
367: GenericValue originalGV = (GenericValue) (originalRow
368: .get(entityNbr));
369:
370: // Process each attribute for this entity.
371: for (int attributeNbr = 0; attributeNbr < getAttributeVector(
372: entityNbr).size(); attributeNbr++) {
373: String attributeName = getAttributeName(entityNbr,
374: attributeNbr);
375: String rowDotEntityDotAttribName = String.valueOf(row)
376: + "." + entityName + "." + attributeName;
377:
378: if (TIMER) {
379: utilTimer.timerString(4,
380: "[DataMatrix.addRowFromHTML] Start processing attribute "
381: + rowDotEntityDotAttribName);
382: }
383:
384: String originalParamName = UIWebUtility.getParamName(
385: UIWebUtility.HTML_NAME_PREFIX_ORIGINAL,
386: uiScreenSection.getSectionName(), entityName,
387: attributeName, row);
388: String currentParamName = UIWebUtility.getParamName(
389: UIWebUtility.HTML_NAME_PREFIX_CURRENT,
390: uiScreenSection.getSectionName(), entityName,
391: attributeName, row);
392:
393: if (request.getParameter(originalParamName) != null) {
394: // This attribute exists in "original" hidden fields in the HTML data. Continue to process it.
395: boolean currentFound = false;
396:
397: if (request.getParameter(currentParamName) == null) {
398: // Attribute does not appear in the "current" parameters. It could be excluded, or it could
399: // be a check box, which would not appear if it is not checked. Continue, but don't set flag.
400: } else {
401: // Attribute appears in the "current" parameters.
402: currentFound = true;
403: }
404:
405: // We will need to determine whether this field is a check box. Get the field info.
406: if (TIMER) {
407: utilTimer.timerString(4,
408: "[DataMatrix.addRowFromHTML] Start getting UIFieldInfo for "
409: + rowDotEntityDotAttribName);
410: }
411:
412: UIFieldInfo uiFieldInfo = uiScreenSection
413: .getUiField(entityName, attributeName);
414:
415: if (TIMER) {
416: utilTimer.timerString(4,
417: "[DataMatrix.addRowFromHTML] Finished getting UIFieldInfo for "
418: + rowDotEntityDotAttribName);
419: }
420:
421: if ((uiFieldInfo != null)
422: && (uiFieldInfo.getDisplayOrder() > 0)) {
423: // The field info was found. Get the display object.
424: if (TIMER) {
425: utilTimer
426: .timerString(
427: 4,
428: "[DataMatrix.addRowFromHTML] Start getting UIDisplayObject for "
429: + rowDotEntityDotAttribName);
430: }
431:
432: UIDisplayObject uiDisplayObject = uiFieldInfo
433: .getUiDisplayObject();
434:
435: if (TIMER) {
436: utilTimer
437: .timerString(
438: 4,
439: "[DataMatrix.addRowFromHTML] Finished getting UIDisplayObject for "
440: + rowDotEntityDotAttribName);
441: }
442:
443: // Find out if this field is a check box. If so, need to use special handling.
444: boolean isCheckbox = false;
445:
446: if (uiDisplayObject.getDisplayTypeId().equals(
447: uiDisplayObject.DISPLAY_TYPE_CHECKBOX)) {
448: isCheckbox = true;
449: }
450:
451: // Make sure the current value was found in the HTML, or that this is a checkbox field,
452: // which would not appear in the HTML if its box is not checked.
453: if (currentFound || isCheckbox) {
454: if (isCheckbox) {
455: // Need to load the display object attributes when there is a check box attribute.
456: if (TIMER) {
457: utilTimer
458: .timerString(
459: 4,
460: "[DataMatrix.addRowFromHTML] Start getting UIDisplayObject attributes for "
461: + rowDotEntityDotAttribName);
462: }
463:
464: uiDisplayObject.loadAttributes();
465:
466: if (TIMER) {
467: utilTimer
468: .timerString(
469: 4,
470: "[DataMatrix.addRowFromHTML] Finished getting UIDisplayObject attributes for "
471: + rowDotEntityDotAttribName);
472: }
473: }
474:
475: // Get the original value and store it in the "original" buffer.
476: String originalAttributeValue = request
477: .getParameter(originalParamName);
478:
479: if (TIMER) {
480: utilTimer
481: .timerString(
482: 4,
483: "[DataMatrix.addRowFromHTML] Start getDataType for "
484: + rowDotEntityDotAttribName);
485: }
486:
487: String fieldType = EventUtility
488: .getDataType(originalGV,
489: attributeName,
490: getDelegator());
491:
492: if (TIMER) {
493: utilTimer
494: .timerString(
495: 4,
496: "[DataMatrix.addRowFromHTML] End getDataType for "
497: + rowDotEntityDotAttribName);
498: }
499:
500: if (TIMER) {
501: utilTimer
502: .timerString(
503: 4,
504: "[DataMatrix.addRowFromHTML] Start storeValue original for "
505: + rowDotEntityDotAttribName);
506: }
507:
508: EventUtility.storeValue(originalGV,
509: attributeName,
510: originalAttributeValue,
511: getDelegator(), fieldType);
512:
513: if (TIMER) {
514: utilTimer
515: .timerString(
516: 4,
517: "[DataMatrix.addRowFromHTML] End storeValue original for "
518: + rowDotEntityDotAttribName);
519: }
520:
521: if (!currentFound) {
522: // Attribute does not appear in the "current" HTML parameters. It must be a checkbox, or this code
523: // would not be executing. Get the unchecked value, and store it in the buffer.
524: EventUtility
525: .storeValue(
526: currentGV,
527: attributeName,
528: uiDisplayObject
529: .getAttribUncheckedValue(),
530: getDelegator(),
531: fieldType);
532:
533: } else {
534: // Attribute does appear in the "current" HTML parameters.
535: if (isCheckbox) {
536: // This is a checked checkbox. Get the checked value, and store it in the current buffer.
537: EventUtility
538: .storeValue(
539: currentGV,
540: attributeName,
541: uiDisplayObject
542: .getAttribCheckedValue(),
543: getDelegator(),
544: fieldType);
545:
546: } else {
547: // Non-checkbox field. Just store the value.
548: String currentAttributeValue = request
549: .getParameter(currentParamName);
550:
551: if (TIMER) {
552: utilTimer
553: .timerString(
554: 4,
555: "[DataMatrix.addRowFromHTML] Calling storeValue for "
556: + rowDotEntityDotAttribName);
557: }
558:
559: EventUtility.storeValue(currentGV,
560: attributeName,
561: currentAttributeValue,
562: getDelegator(), fieldType);
563:
564: if (TIMER) {
565: utilTimer
566: .timerString(
567: 4,
568: "[DataMatrix.addRowFromHTML] Finished storeValue for "
569: + rowDotEntityDotAttribName);
570: }
571:
572: }
573: }
574: }
575: }
576: }
577: }
578: }
579:
580: // Store the new row in each buffer.
581: getCurrentBuffer().addContentsRow(currentRow);
582: getOriginalBuffer().addContentsRow(originalRow);
583:
584: // Check for delete flag for the new row.
585: if (request.getParameter("deleteFlag" + String.valueOf(row)) != null) {
586: // The user specified for this row to be deleted. Set the delete flag to true for this row.
587: addDeleteFlag(true);
588: } else {
589: // Either there was no delete check box, or it was not checked. Set delete flag to false for this row.
590: addDeleteFlag(false);
591: }
592:
593: if (TIMER) {
594: utilTimer.timerString(4, "[DataMatrix.addRowFromHTML] End");
595: }
596:
597: return;
598: }
599:
600: public void addRowFromArray(int row, Vector dataValues,
601: Vector importFields, UIScreenSection uiScreenSection)
602: throws GenericEntityException {
603: UtilTimer utilTimer = new UtilTimer();
604:
605: if (TIMER) {
606: utilTimer.timerString(4,
607: "[DataMatrix.addRowFromArray] Start");
608: }
609:
610: // Create an empty row to be updated and stored in the current and original buffers.
611: Vector currentRow = getCurrentBuffer().getContentsRow(0);
612: Vector originalRow = getOriginalBuffer().getContentsRow(0);
613: if (currentRow == null) {
614: currentRow = getCurrentBuffer().createEmptyRow();
615: }
616: if (originalRow == null) {
617: originalRow = getOriginalBuffer().createEmptyRow();
618: }
619:
620: for (int fieldNum = 0; fieldNum < dataValues.size(); fieldNum++) {
621: String paramName = (String) importFields.get(fieldNum);
622:
623: if ((paramName == null) || (paramName.length() == 0)) {
624: continue;
625: }
626:
627: String paramEntityName = UIWebUtility
628: .getEntityFromParamName(paramName);
629: String paramAttributeName = UIWebUtility
630: .getAttribFromParamName(paramName);
631:
632: String paramDataValue = (String) dataValues.get(fieldNum);
633:
634: // Loop through the entities and attributes for the current screen section, and get the value
635: // from the request object for each one, and store it in the contents.
636: for (int entityNbr = 0; entityNbr < getEntityParamVector()
637: .size(); entityNbr++) {
638: String entityName = getEntityName(entityNbr);
639:
640: if (TIMER) {
641: utilTimer.timerString(4,
642: "[DataMatrix.addRowFromArray] Start processing entity "
643: + String.valueOf(entityNbr) + " ("
644: + entityName + ")");
645: }
646:
647: if (entityName.equals(paramEntityName)) {
648: // Get references to the orginal and current generic values for this entity.
649: GenericValue currentGV = (GenericValue) (currentRow
650: .get(entityNbr));
651: String fieldType = EventUtility.getDataType(
652: currentGV, paramAttributeName,
653: getDelegator());
654: EventUtility.storeValue(currentGV,
655: paramAttributeName, paramDataValue,
656: getDelegator(), fieldType);
657: }
658: }
659: }
660:
661: // Store the new row in each buffer.
662: getCurrentBuffer().setContentsRow(0, currentRow);
663: getOriginalBuffer().setContentsRow(0, originalRow);
664:
665: if (TIMER) {
666: utilTimer
667: .timerString(4, "[DataMatrix.addRowFromArray] End");
668: }
669:
670: return;
671: }
672:
673: /**
674: * DOCUMENT ME!
675: *
676: * @param row
677: * @param request
678: * @param dataValues
679: * @param importFields
680: * @param uiScreenSection
681: *
682: * @throws GenericEntityException
683: */
684: public void addRowFromArray(int row, String[] dataValues,
685: Vector importFields, UIScreenSection uiScreenSection)
686: throws GenericEntityException {
687:
688: Vector values = new Vector(Arrays.asList(dataValues));
689: addRowFromArray(row, values, importFields, uiScreenSection);
690: return;
691: }
692:
693: /**
694: * DOCUMENT ME!
695: *
696: * @param row
697: *
698: * @return
699: */
700: public boolean getRowChanged(int row) {
701: // Compare all fields in the current generic value with the ones in the original generic value
702: // to see if the user changed any values in the current row.
703: Vector currentRow = getCurrentBuffer().getContentsRow(row);
704: Vector originalRow = getOriginalBuffer().getContentsRow(row);
705: boolean rowChanged = false;
706:
707: for (int entityNumber = 0; entityNumber < currentRow.size(); entityNumber++) {
708: if (getIsUpdateable(entityNumber)) {
709: // This entity is updateable. See if any values changed in its generic value.
710: GenericValue currentGV = (GenericValue) currentRow
711: .get(entityNumber);
712: GenericValue originalGV = (GenericValue) originalRow
713: .get(entityNumber);
714:
715: if (!currentGV.equals(originalGV)) {
716: rowChanged = true;
717:
718: break;
719: }
720: }
721: }
722:
723: return rowChanged;
724: }
725:
726: public static DataMatrix fillFromDB(GenericDelegator delegator,
727: UserInfo userInfo, UIScreenSection uiScreenSection,
728: GenericEventProcessor eventProcessor, GenericPK primaryKey) {
729: try {
730: DataMatrix dataMatrix = new DataMatrix(delegator,
731: uiScreenSection.getEntityParamVector());
732:
733: String primaryEntityName = uiScreenSection
734: .getUiScreenSectionEntity(0).getUiEntity()
735: .getEntityName();
736: // Specify how the primary entity will be retrieved.
737: ArrayList orderBy = new ArrayList();
738: QueryInfo queryInfo = new QueryInfo(delegator,
739: primaryEntityName);
740: Enumeration params = null;
741: String searchAttribValue = "";
742: String searchEntityName = "";
743: String searchAttribName = "";
744: String queryName = "";
745: EntityComparisonOperator entityOperator = null;
746: List relatedSearchClauses = new LinkedList();
747: List primaryPkFieldNames = uiScreenSection
748: .getUiScreenSectionEntity(0).getUiEntity()
749: .getPrimaryKeyFieldNames();
750:
751: Map fields = primaryKey.getAllFields();
752:
753: // Specify how associated entities will be retrieved.
754: Iterator uiScreenSectionEntityI = uiScreenSection
755: .getUiScreenSectionEntityList().iterator();
756: uiScreenSectionEntityI.next(); // Pass up the primary entity.
757:
758: while (uiScreenSectionEntityI.hasNext()) {
759: UIScreenSectionEntity uiScreenSectionEntity = (UIScreenSectionEntity) uiScreenSectionEntityI
760: .next();
761: relatedSearchClauses.add(uiScreenSectionEntity);
762: }
763:
764: uiScreenSectionEntityI = null; // Reset the iterator.
765:
766: // Specify the sort order.
767: orderBy = new DelimitedValueDecoder(uiScreenSection
768: .getSortDef()).decode();
769:
770: eventProcessor.processRetrieve(userInfo, primaryEntityName,
771: eventProcessor.RETRIEVE_METHOD_PK, fields, orderBy,
772: queryInfo, relatedSearchClauses, delegator,
773: dataMatrix);
774:
775: return dataMatrix;
776: } catch (Exception e) {
777: Debug.logError(e, module);
778: }
779: return null;
780: }
781: }
|