Skip to content

Package: EMFFormsSpreadsheetSingleAttributeConverter

EMFFormsSpreadsheetSingleAttributeConverter

nameinstructionbranchcomplexitylinemethod
EMFFormsSpreadsheetSingleAttributeConverter()
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
convertCellToBigDecimal(Cell)
M: 0 C: 17
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
convertCellToBigInteger(Cell)
M: 0 C: 14
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
convertCellToXMLDate(Cell, boolean)
M: 3 C: 36
92%
M: 3 C: 3
50%
M: 3 C: 1
25%
M: 1 C: 11
92%
M: 0 C: 1
100%
getCellValue(Cell, EStructuralFeature)
M: 4 C: 87
96%
M: 2 C: 4
67%
M: 2 C: 2
50%
M: 2 C: 17
89%
M: 0 C: 1
100%
isApplicable(EObject, VDomainModelReference)
M: 0 C: 25
100%
M: 0 C: 6
100%
M: 0 C: 4
100%
M: 0 C: 10
100%
M: 0 C: 1
100%
isBigDecimal(Class)
M: 0 C: 8
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
isBigInteger(Class)
M: 0 C: 8
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
isBoolean(Class)
M: 0 C: 15
100%
M: 0 C: 6
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
isByte(Class)
M: 0 C: 15
100%
M: 0 C: 6
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
isDate(Class)
M: 0 C: 8
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
isDate(EDataType)
M: 8 C: 26
76%
M: 2 C: 4
67%
M: 2 C: 2
50%
M: 2 C: 8
80%
M: 0 C: 1
100%
isDouble(Class)
M: 0 C: 15
100%
M: 0 C: 6
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
isFloat(Class)
M: 0 C: 15
100%
M: 0 C: 6
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
isInteger(Class)
M: 0 C: 15
100%
M: 0 C: 6
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
isLong(Class)
M: 0 C: 15
100%
M: 0 C: 6
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
isShort(Class)
M: 0 C: 15
100%
M: 0 C: 6
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
isXMLDate(Class)
M: 0 C: 8
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
readCellValue(Cell, EDataType)
M: 0 C: 112
100%
M: 0 C: 24
100%
M: 0 C: 13
100%
M: 0 C: 25
100%
M: 0 C: 1
100%
setCellValue(Cell, Object, EStructuralFeature, ViewModelContext)
M: 10 C: 143
93%
M: 2 C: 26
93%
M: 2 C: 13
87%
M: 2 C: 32
94%
M: 0 C: 1
100%
setDatabinding(EMFFormsDatabindingEMF)
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
setReportService(ReportService)
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
writeBigDecimal(Cell, Object, ViewModelContext, EAttribute)
M: 6 C: 34
85%
M: 2 C: 4
67%
M: 2 C: 2
50%
M: 1 C: 10
91%
M: 0 C: 1
100%
writeBigInteger(Cell, Object, ViewModelContext)
M: 0 C: 31
100%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 0 C: 8
100%
M: 0 C: 1
100%
writeFloatDouble(Cell, Object, ViewModelContext, EAttribute)
M: 6 C: 13
68%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 1 C: 4
80%
M: 0 C: 1
100%

Coverage

1: /*******************************************************************************
2: * Copyright (c) 2011-2015 EclipseSource Muenchen GmbH and others.
3: *
4: * All rights reserved. This program and the accompanying materials
5: * are made available under the terms of the Eclipse Public License 2.0
6: * which accompanies this distribution, and is available at
7: * https://www.eclipse.org/legal/epl-2.0/
8: *
9: * SPDX-License-Identifier: EPL-2.0
10: *
11: * Contributors:
12: * Johannes Faltermeier - initial API and implementation
13: ******************************************************************************/
14: package org.eclipse.emfforms.internal.spreadsheet.core.converter;
15:
16: import java.math.BigDecimal;
17: import java.math.BigInteger;
18: import java.util.Calendar;
19: import java.util.Date;
20: import java.util.TimeZone;
21:
22: import javax.xml.datatype.DatatypeConstants;
23: import javax.xml.datatype.XMLGregorianCalendar;
24:
25: import org.apache.poi.ss.usermodel.Cell;
26: import org.apache.poi.ss.usermodel.CellStyle;
27: import org.apache.poi.ss.usermodel.DateUtil;
28: import org.eclipse.emf.common.util.EMap;
29: import org.eclipse.emf.ecore.EAnnotation;
30: import org.eclipse.emf.ecore.EAttribute;
31: import org.eclipse.emf.ecore.EDataType;
32: import org.eclipse.emf.ecore.EObject;
33: import org.eclipse.emf.ecore.EStructuralFeature;
34: import org.eclipse.emf.ecore.util.EcoreUtil;
35: import org.eclipse.emf.ecore.xml.type.internal.XMLCalendar;
36: import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
37: import org.eclipse.emf.ecp.view.spi.model.VDomainModelReference;
38: import org.eclipse.emfforms.spi.common.report.ReportService;
39: import org.eclipse.emfforms.spi.core.services.databinding.emf.EMFFormsDatabindingEMF;
40: import org.eclipse.emfforms.spi.spreadsheet.core.converter.EMFFormsCellStyleConstants;
41: import org.eclipse.emfforms.spi.spreadsheet.core.converter.EMFFormsConverterException;
42: import org.eclipse.emfforms.spi.spreadsheet.core.converter.EMFFormsSpreadsheetValueConverter;
43: import org.eclipse.emfforms.spi.spreadsheet.core.converter.EMFFormsSpreadsheetValueConverterHelper;
44: import org.osgi.service.component.annotations.Component;
45: import org.osgi.service.component.annotations.Reference;
46: import org.osgi.service.component.annotations.ReferenceCardinality;
47:
48: /**
49: * {@link EMFFormsSpreadsheetValueConverter Converter} for single {@link EAttribute attributes}.
50: *
51: * @author Johannes Faltermeier
52: *
53: */
54: @Component(name = "EMFFormsSpreadsheetSingleAttributeConverter")
55: public class EMFFormsSpreadsheetSingleAttributeConverter implements EMFFormsSpreadsheetValueConverter {
56:
57:         private static final int DOUBLE_PRECISION = 16;
58:         private EMFFormsDatabindingEMF databinding;
59:         private ReportService reportService;
60:
61:         /**
62:          * Sets the databinding service.
63:          *
64:          * @param databinding the service
65:          */
66:         @Reference(cardinality = ReferenceCardinality.MANDATORY, unbind = "-")
67:         public void setDatabinding(EMFFormsDatabindingEMF databinding) {
68:                 this.databinding = databinding;
69:         }
70:
71:         /**
72:          * Sets the report service.
73:          *
74:          * @param reportService the service
75:          */
76:         @Reference(cardinality = ReferenceCardinality.MANDATORY, unbind = "-")
77:         public void setReportService(ReportService reportService) {
78:                 this.reportService = reportService;
79:         }
80:
81:         @Override
82:         public double isApplicable(EObject domainObject, VDomainModelReference dmr) {
83:                 final EStructuralFeature feature = EMFFormsSpreadsheetValueConverterHelper.getFeature(domainObject, dmr,
84:                         databinding,
85:                         reportService);
86:•                if (feature == null) {
87:                         return NOT_APPLICABLE;
88:                 }
89:•                if (!EAttribute.class.isInstance(feature)) {
90:                         return NOT_APPLICABLE;
91:                 }
92:•                if (feature.isMany()) {
93:                         return NOT_APPLICABLE;
94:                 }
95:                 return 0d;
96:         }
97:
98:         /**
99:          * {@inheritDoc}
100:          *
101:          * @see org.eclipse.emfforms.spi.spreadsheet.core.converter.EMFFormsSpreadsheetValueConverter#setCellValue(org.apache.poi.ss.usermodel.Cell,
102:          * java.lang.Object, org.eclipse.emf.ecore.EStructuralFeature,
103:          * org.eclipse.emf.ecp.view.spi.context.ViewModelContext)
104:          */
105:         @Override
106:         public void setCellValue(Cell cell, Object value, EStructuralFeature eStructuralFeature,
107:                 ViewModelContext viewModelContext)
108:                 throws EMFFormsConverterException {
109:•                if (value == null) {
110:                         return;
111:                 }
112:                 final EAttribute eAttribute = EAttribute.class.cast(eStructuralFeature);
113:•                if (eAttribute == null) {
114:                         throw new EMFFormsConverterException("The provided eAttribute is null."); //$NON-NLS-1$
115:                 }
116:                 final EDataType attributeType = eAttribute.getEAttributeType();
117:•                if (attributeType == null) {
118:                         throw new EMFFormsConverterException("The attributeType of the provided eAttribute is null."); //$NON-NLS-1$
119:                 }
120:
121:•                if (isBoolean(attributeType.getInstanceClass())) {
122:                         cell.setCellValue(Boolean.class.cast(value));
123:•                } else if (isByte(attributeType.getInstanceClass()) ||
124:•                        isShort(attributeType.getInstanceClass()) ||
125:•                        isInteger(attributeType.getInstanceClass()) ||
126:•                        isLong(attributeType.getInstanceClass())) {
127:                         cell.setCellValue(Number.class.cast(value).doubleValue());
128:•                } else if (isFloat(attributeType.getInstanceClass()) ||
129:•                        isDouble(attributeType.getInstanceClass())) {
130:                         writeFloatDouble(cell, value, viewModelContext, eAttribute);
131:•                } else if (isBigInteger(attributeType.getInstanceClass())) {
132:                         writeBigInteger(cell, value, viewModelContext);
133:•                } else if (isBigDecimal(attributeType.getInstanceClass())) {
134:                         writeBigDecimal(cell, value, viewModelContext, eAttribute);
135:•                } else if (isDate(attributeType.getInstanceClass())) {
136:                         cell.setCellValue(DateUtil.getExcelDate(Date.class.cast(value)));
137:                         cell.setCellStyle((CellStyle) viewModelContext.getContextValue(EMFFormsCellStyleConstants.DATE));
138:•                } else if (isXMLDate(attributeType.getInstanceClass())) {
139:                         final XMLGregorianCalendar xmlDate = XMLGregorianCalendar.class.cast(value);
140:                         cell.setCellValue(
141:                                 DateUtil.getExcelDate(xmlDate.toGregorianCalendar(TimeZone.getTimeZone("UTC"), null, xmlDate), false)); //$NON-NLS-1$
142:                         cell.setCellStyle((CellStyle) viewModelContext.getContextValue(EMFFormsCellStyleConstants.DATE));
143:                 } else {
144:                         cell.setCellValue(EcoreUtil.convertToString(attributeType, value));
145:                         cell.setCellStyle((CellStyle) viewModelContext.getContextValue(EMFFormsCellStyleConstants.TEXT));
146:                 }
147:         }
148:
149:         private void writeFloatDouble(Cell cell, Object value, ViewModelContext viewModelContext,
150:                 final EAttribute eAttribute) {
151:                 cell.setCellValue(Number.class.cast(value).doubleValue());
152:                 final String format = NumberFormatHelper.getNumberFormat(eAttribute);
153:•                if (format != null) {
154:                         cell.setCellStyle((CellStyle) viewModelContext.getContextValue(format));
155:                 }
156:         }
157:
158:         private void writeBigDecimal(Cell cell, Object value, ViewModelContext viewModelContext, EAttribute eAttribute) {
159:                 final BigDecimal bigDecimal = BigDecimal.class.cast(value);
160:•                if (Double.isInfinite(bigDecimal.doubleValue())
161:•                        || bigDecimal.precision() > DOUBLE_PRECISION) {
162:                         cell.setCellValue(bigDecimal.toString());
163:                         cell.setCellStyle((CellStyle) viewModelContext.getContextValue(EMFFormsCellStyleConstants.TEXT));
164:                 } else {
165:                         cell.setCellValue(bigDecimal.doubleValue());
166:                         final String format = NumberFormatHelper.getNumberFormat(eAttribute);
167:•                        if (format != null) {
168:                                 cell.setCellStyle((CellStyle) viewModelContext.getContextValue(format));
169:                         }
170:                 }
171:         }
172:
173:         private void writeBigInteger(Cell cell, Object value, ViewModelContext viewModelContext) {
174:                 final BigInteger bigInteger = BigInteger.class.cast(value);
175:•                if (bigInteger.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0
176:•                        || bigInteger.compareTo(BigInteger.valueOf(Long.MIN_VALUE)) < 0) {
177:                         cell.setCellValue(bigInteger.toString());
178:                         cell.setCellStyle((CellStyle) viewModelContext.getContextValue(EMFFormsCellStyleConstants.TEXT));
179:                 } else {
180:                         cell.setCellValue(bigInteger.doubleValue());
181:                 }
182:         }
183:
184:         /**
185:          * {@inheritDoc}
186:          *
187:          * @see org.eclipse.emfforms.spi.spreadsheet.core.converter.EMFFormsSpreadsheetValueConverter#getCellValue(org.apache.poi.ss.usermodel.Cell,
188:          * org.eclipse.emf.ecore.EStructuralFeature)
189:          */
190:         @Override
191:         public Object getCellValue(Cell cell, EStructuralFeature eStructuralFeature) throws EMFFormsConverterException {
192:                 final EAttribute eAttribute = EAttribute.class.cast(eStructuralFeature);
193:•                if (cell.getCellType() == Cell.CELL_TYPE_BLANK) {
194:                         return null;
195:                 }
196:•                if (eAttribute == null) {
197:                         return null;
198:                 }
199:                 final EDataType attributeType = eAttribute.getEAttributeType();
200:•                if (attributeType == null) {
201:                         return null;
202:                 }
203:                 try {
204:                         return readCellValue(cell, attributeType);
205:                 } catch (final IllegalStateException e) {
206:                         throw new EMFFormsConverterException(
207:                                 String.format("Cell value of column %1$s in row %2$s on sheet %3$s must be a string.", //$NON-NLS-1$
208:                                         cell.getColumnIndex() + 1, cell.getRowIndex() + 1, cell.getSheet().getSheetName()),
209:                                 e);
210:                 } catch (final NumberFormatException e) {
211:                         throw new EMFFormsConverterException(
212:                                 String.format("Cell value of column %1$s in row %2$s on sheet %3$s is not a valid number.", //$NON-NLS-1$
213:                                         cell.getColumnIndex() + 1, cell.getRowIndex() + 1, cell.getSheet().getSheetName()),
214:                                 e);
215:                 }
216:         }
217:
218:         private Object readCellValue(Cell cell, final EDataType attributeType) {
219:•                if (isByte(attributeType.getInstanceClass())) {
220:                         return Double.valueOf(cell.getNumericCellValue()).byteValue();
221:•                } else if (isShort(attributeType.getInstanceClass())) {
222:                         return Double.valueOf(cell.getNumericCellValue()).shortValue();
223:•                } else if (isInteger(attributeType.getInstanceClass())) {
224:                         return Double.valueOf(cell.getNumericCellValue()).intValue();
225:•                } else if (isLong(attributeType.getInstanceClass())) {
226:                         return Double.valueOf(cell.getNumericCellValue()).longValue();
227:•                } else if (isFloat(attributeType.getInstanceClass())) {
228:                         return Double.valueOf(cell.getNumericCellValue()).floatValue();
229:•                } else if (isDouble(attributeType.getInstanceClass())) {
230:                         return cell.getNumericCellValue();
231:•                } else if (isBigInteger(attributeType.getInstanceClass())) {
232:                         return convertCellToBigInteger(cell);
233:•                } else if (isBigDecimal(attributeType.getInstanceClass())) {
234:                         return convertCellToBigDecimal(cell);
235:•                } else if (isBoolean(attributeType.getInstanceClass())) {
236:                         return cell.getBooleanCellValue();
237:•                } else if (isDate(attributeType.getInstanceClass())) {
238:                         return DateUtil.getJavaDate(cell.getNumericCellValue());
239:•                } else if (isXMLDate(attributeType.getInstanceClass())) {
240:                         return convertCellToXMLDate(cell, isDate(attributeType));
241:                 } else {
242:•                        if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
243:                                 cell.setCellType(Cell.CELL_TYPE_STRING);
244:                         }
245:                         return EcoreUtil.createFromString(attributeType, cell.getStringCellValue());
246:                 }
247:         }
248:
249:         private boolean isDate(EDataType attributeType) {
250:                 final EAnnotation eAnnotation = attributeType
251:                         .getEAnnotation("http:///org/eclipse/emf/ecore/util/ExtendedMetaData");//$NON-NLS-1$
252:•                if (eAnnotation == null) {
253:                         return true;
254:                 }
255:                 final EMap<String, String> typeDetails = eAnnotation.getDetails();
256:•                if (typeDetails.containsKey("name")) {//$NON-NLS-1$
257:                         return "date".equals(typeDetails.get("name"));//$NON-NLS-1$//$NON-NLS-2$
258:                 }
259:•                if (typeDetails.containsKey("baseType")) {//$NON-NLS-1$
260:                         return typeDetails.get("baseType").endsWith("date");//$NON-NLS-1$//$NON-NLS-2$
261:                 }
262:                 return true;
263:         }
264:
265:         private XMLGregorianCalendar convertCellToXMLDate(Cell cell, boolean isDate) {
266:                 final Calendar targetCal = DateUtil.getJavaCalendarUTC(cell.getNumericCellValue(), false);
267:•                if (targetCal == null) {
268:                         return null;
269:                 }
270:                 final XMLGregorianCalendar cal = new XMLCalendar(targetCal.getTime(),
271:•                        isDate ? XMLCalendar.DATE : XMLCalendar.DATETIME);
272:•                if (isDate) {
273:                         cal.setTimezone(DatatypeConstants.FIELD_UNDEFINED);
274:                         cal.setHour(DatatypeConstants.FIELD_UNDEFINED);
275:                         cal.setMinute(DatatypeConstants.FIELD_UNDEFINED);
276:                         cal.setSecond(DatatypeConstants.FIELD_UNDEFINED);
277:                         cal.setMillisecond(DatatypeConstants.FIELD_UNDEFINED);
278:                 }
279:                 return cal;
280:         }
281:
282:         private BigDecimal convertCellToBigDecimal(Cell cell) {
283:•                if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
284:                         return BigDecimal.valueOf(cell.getNumericCellValue()).stripTrailingZeros();
285:                 }
286:                 final String value = cell.getStringCellValue();
287:                 return new BigDecimal(value).stripTrailingZeros();
288:         }
289:
290:         private BigInteger convertCellToBigInteger(Cell cell) {
291:•                if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
292:                         return BigInteger.valueOf((long) cell.getNumericCellValue());
293:                 }
294:                 return new BigInteger(cell.getStringCellValue());
295:         }
296:
297:         private static boolean isXMLDate(final Class<?> clazz) {
298:•                if (clazz == null) {
299:                         return false;
300:                 }
301:                 return XMLGregorianCalendar.class.isAssignableFrom(clazz);
302:         }
303:
304:         private static boolean isDate(final Class<?> clazz) {
305:•                if (clazz == null) {
306:                         return false;
307:                 }
308:                 return Date.class.isAssignableFrom(clazz);
309:         }
310:
311:         private static boolean isBigDecimal(final Class<?> clazz) {
312:•                if (clazz == null) {
313:                         return false;
314:                 }
315:                 return BigDecimal.class.isAssignableFrom(clazz);
316:         }
317:
318:         private static boolean isBigInteger(final Class<?> clazz) {
319:•                if (clazz == null) {
320:                         return false;
321:                 }
322:                 return BigInteger.class.isAssignableFrom(clazz);
323:         }
324:
325:         private static boolean isBoolean(final Class<?> clazz) {
326:•                if (clazz == null) {
327:                         return false;
328:                 }
329:•                return Boolean.TYPE == clazz || Boolean.class.isAssignableFrom(clazz);
330:         }
331:
332:         private static boolean isDouble(final Class<?> clazz) {
333:•                if (clazz == null) {
334:                         return false;
335:                 }
336:•                return Double.TYPE == clazz || Double.class.isAssignableFrom(clazz);
337:         }
338:
339:         private static boolean isFloat(final Class<?> clazz) {
340:•                if (clazz == null) {
341:                         return false;
342:                 }
343:•                return Float.TYPE == clazz || Float.class.isAssignableFrom(clazz);
344:         }
345:
346:         private static boolean isLong(final Class<?> clazz) {
347:•                if (clazz == null) {
348:                         return false;
349:                 }
350:•                return Long.TYPE == clazz || Long.class.isAssignableFrom(clazz);
351:         }
352:
353:         private static boolean isInteger(Class<?> clazz) {
354:•                if (clazz == null) {
355:                         return false;
356:                 }
357:•                return Integer.TYPE == clazz || Integer.class.isAssignableFrom(clazz);
358:         }
359:
360:         private static boolean isShort(Class<?> clazz) {
361:•                if (clazz == null) {
362:                         return false;
363:                 }
364:•                return Short.TYPE == clazz || Short.class.isAssignableFrom(clazz);
365:         }
366:
367:         private static boolean isByte(Class<?> clazz) {
368:•                if (clazz == null) {
369:                         return false;
370:                 }
371:•                return Byte.TYPE == clazz || Byte.class.isAssignableFrom(clazz);
372:         }
373: }