private static Map<Object, IRecord> getRecordsById( List<IRecord> updatedOrAdded, int idFieldIndex) { Map<Object, IRecord> res = new HashMap<Object, IRecord>(updatedOrAdded.size()); for (IRecord iRecord : updatedOrAdded) { IField fieldId = iRecord.getFieldAt(idFieldIndex); Assert.assertNotNull(fieldId, "fieldId"); Object value = fieldId.getValue(); Assert.assertNotNull(value, "value"); res.put(value, iRecord); } return res; }
private static List<IRecord> getAdded( IDataStore prev, RecordRetriever currRetr, int prevFieldIndex) { List<IRecord> added = new ArrayList<IRecord>(); for (int i = 0; i < currRetr.countRecords(); i++) { IRecord currRec = currRetr.getRecord(i); IField currIdField = currRec.getFieldAt(prevFieldIndex); Assert.assertNotNull(currIdField, "currId"); Object id = currIdField.getValue(); Assert.assertNotNull(id, "id"); if (prev.getRecordByID(id) == null) { added.add(currRec); } } return added; }
private static List<IRecord> getDeleted(IDataStore prev, IDataStore curr, int prevFieldIndex) { List<IRecord> deleted = new ArrayList<IRecord>(); for (int i = 0; i < prev.getRecordsCount(); i++) { IRecord prevRec = prev.getRecordAt(i); IField prevIdField = prevRec.getFieldAt(prevFieldIndex); Assert.assertNotNull(prevIdField, "prevIdField"); Object prevId = prevIdField.getValue(); Assert.assertNotNull(prevId, "prevId"); IRecord currRec = curr.getRecordByID(prevId); if (currRec == null) { deleted.add(prevRec); continue; } } return deleted; }
private static List<IRecord> getUpdated( IDataStore prev, RecordIdRetriever currRetr, int prevFieldIndex) { List<IRecord> updated = new ArrayList<IRecord>(); for (int i = 0; i < prev.getRecordsCount(); i++) { IRecord prevRec = prev.getRecordAt(i); IField prevIdField = prevRec.getFieldAt(prevFieldIndex); Assert.assertNotNull(prevIdField, "prevIdField"); Object prevId = prevIdField.getValue(); Assert.assertNotNull(prevId, "prevId"); IRecord currRec = currRetr.getRecordById(prevId); if (currRec == null) { // deleted continue; } // check updated by position of field // a impossible improvement: check the changes by field meta's name List<IField> prevFields = prevRec.getFields(); List<IField> currFields = currRec.getFields(); if (prevFields.size() != currFields.size()) { updated.add(currRec); continue; } // check updated by checking fields values for (int j = 0; j < prevFields.size(); j++) { IField prevField = prevFields.get(j); IField currField = currFields.get(j); Assert.assertNotNull(prevField, "prevField"); Assert.assertNotNull(currField, "currField"); Object prevValue = prevField.getValue(); Object currValue = currField.getValue(); boolean equals = areEquals(prevValue, currValue); if (!equals) { updated.add(currRec); break; } } } return updated; }
private void addSumRows(IDataStore dataStore) { logger.debug("IN"); summaryColorCellsArray = new JSONArray(); summaryCellsArray = new JSONArray(); ArrayList<Integer> columnsIndexToMerge = new ArrayList<Integer>(); ArrayList<Integer> columnsIndexToEmpty = new ArrayList<Integer>(); ArrayList<Integer> columnsIndexToAfter = new ArrayList<Integer>(); HashMap<Integer, Object> columnsIndexToSum2Counter = new HashMap<Integer, Object>(); // collect columns to merge and columns to sum and colummsn to empty: // -- columns to merge have merge attributes until a columns with summaryFunc is found // then other columns that have merge attribute but no List<Column> columns = registryConfig.getColumns(); Integer index = 0; boolean summaryFuncFound = false; boolean measureFound = false; for (Iterator iterator = columns.iterator(); iterator.hasNext(); ) { Column column = (Column) iterator.next(); if (column.isMerge() && summaryFuncFound == false) { columnsIndexToMerge.add(index); } else if (summaryFuncFound == true && !column.isMeasure() && !measureFound) { columnsIndexToEmpty.add(index); } else if (summaryFuncFound == true && !column.isMeasure() && measureFound) { columnsIndexToAfter.add(index); } else if (column.isMeasure()) { columnsIndexToSum2Counter.put(index, 0); measureFound = true; } if (column.getSummaryFunction() != null && column.getSummaryFunction().equals("sum")) summaryFuncFound = true; index++; } // Map to store previous merge values on iteration HashMap<Integer, Object> previousMergeValues = new HashMap<Integer, Object>(); for (Iterator iterator = columnsIndexToMerge.iterator(); iterator.hasNext(); ) { Integer columnIndex = (Integer) iterator.next(); previousMergeValues.put(columnIndex, null); } TreeMap<Integer, Record> recordsToAddMap = new TreeMap<Integer, Record>(); int sumCounter = 0; // add total row only if grouping has more than one member // iterate on each store row for (int i = 0; i < dataStore.getRecordsCount(); i++) { IRecord record = dataStore.getRecordAt(i); // get current values of column to merge HashMap<Integer, Object> currentMergeValues = new HashMap<Integer, Object>(); // iterate on each column to merge and store values for (Iterator iterator = columnsIndexToMerge.iterator(); iterator.hasNext(); ) { Integer columnIndex = (Integer) iterator.next(); Object value = record.getFieldAt(columnIndex).getValue(); currentMergeValues.put(columnIndex, value); } // compare current values with previous ones boolean isEqual = compareValuesMaps(previousMergeValues, currentMergeValues); // if merging goes on update counters else add summarization line if (isEqual) { sumCounter++; for (Iterator iterator = columnsIndexToSum2Counter.keySet().iterator(); iterator.hasNext(); ) { Integer indexMeasure = (Integer) iterator.next(); Object value = record.getFieldAt(indexMeasure).getValue(); // TODO treat the case this is not a number, should keep it to null if (value != null) { // get previous value Object result = operateWithNumbers(columnsIndexToSum2Counter.get(indexMeasure), value); columnsIndexToSum2Counter.put(indexMeasure, result); } else { columnsIndexToSum2Counter.put(indexMeasure, null); } } } else { // breaking point, add summarization lines at previous index; i-1 // add a new record only if sumCounter > 0 if (sumCounter > 0) { addTotalRecord( dataStore, i, columnsIndexToMerge, columnsIndexToEmpty, columnsIndexToAfter, columnsIndexToSum2Counter, previousMergeValues, recordsToAddMap); } // put the counters to actual values for (Iterator iterator = columnsIndexToSum2Counter.keySet().iterator(); iterator.hasNext(); ) { Integer columnInd = (Integer) iterator.next(); Object v = record.getFieldAt(columnInd).getValue(); columnsIndexToSum2Counter.put(columnInd, v); } sumCounter = 0; } // update previousValues previousMergeValues = currentMergeValues; } // add final total if last records were merged if (sumCounter > 0) { addTotalRecord( dataStore, null, columnsIndexToMerge, columnsIndexToEmpty, columnsIndexToAfter, columnsIndexToSum2Counter, previousMergeValues, recordsToAddMap); } // finally add the record (could not add them while cycling the store) for (Iterator iterator = recordsToAddMap.keySet().iterator(); iterator.hasNext(); ) { Integer indexR = (Integer) iterator.next(); Record rec = recordsToAddMap.get(indexR); if (indexR == -1) { dataStore.appendRecord(rec); } else { dataStore.insertRecord(indexR, rec); } } logger.debug("OUT"); }