Skip to content

Package: EMFFormsSpreadsheetImporterImpl$MigrationInformation$State

EMFFormsSpreadsheetImporterImpl$MigrationInformation$State

nameinstructionbranchcomplexitylinemethod
static {...}
M: 0 C: 34
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 7
100%
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: * Eugen Neufeld - initial API and implementation
13: ******************************************************************************/
14: package org.eclipse.emfforms.internal.spreadsheet.core.transfer;
15:
16: import java.io.IOException;
17: import java.text.MessageFormat;
18: import java.util.ArrayList;
19: import java.util.Collection;
20: import java.util.Collections;
21: import java.util.LinkedHashMap;
22: import java.util.LinkedHashSet;
23: import java.util.List;
24: import java.util.Map;
25: import java.util.Set;
26:
27: import org.apache.poi.ss.usermodel.Cell;
28: import org.apache.poi.ss.usermodel.Comment;
29: import org.apache.poi.ss.usermodel.Row;
30: import org.apache.poi.ss.usermodel.Sheet;
31: import org.apache.poi.ss.usermodel.Workbook;
32: import org.eclipse.emf.common.command.BasicCommandStack;
33: import org.eclipse.emf.common.util.URI;
34: import org.eclipse.emf.ecore.EClass;
35: import org.eclipse.emf.ecore.EObject;
36: import org.eclipse.emf.ecore.EStructuralFeature;
37: import org.eclipse.emf.ecore.EStructuralFeature.Setting;
38: import org.eclipse.emf.ecore.resource.Resource;
39: import org.eclipse.emf.ecore.resource.ResourceSet;
40: import org.eclipse.emf.ecore.resource.URIConverter.ReadableInputStream;
41: import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
42: import org.eclipse.emf.ecore.util.EcoreUtil;
43: import org.eclipse.emf.ecp.spi.view.migrator.string.StringViewModelMigrator;
44: import org.eclipse.emf.ecp.spi.view.migrator.string.StringViewModelMigratorUtil;
45: import org.eclipse.emf.ecp.view.migrator.ViewModelMigrationException;
46: import org.eclipse.emf.ecp.view.migrator.ViewModelMigratorUtil;
47: import org.eclipse.emf.ecp.view.spi.model.VDomainModelReference;
48: import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
49: import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
50: import org.eclipse.emfforms.internal.spreadsheet.core.transfer.EMFFormsSpreadsheetImporterImpl.MigrationInformation.State;
51: import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedException;
52: import org.eclipse.emfforms.spi.core.services.databinding.emf.EMFFormsDatabindingEMF;
53: import org.eclipse.emfforms.spi.core.services.domainexpander.EMFFormsDomainExpander;
54: import org.eclipse.emfforms.spi.core.services.domainexpander.EMFFormsExpandingFailedException;
55: import org.eclipse.emfforms.spi.localization.LocalizationServiceHelper;
56: import org.eclipse.emfforms.spi.spreadsheet.core.EMFFormsIdProvider;
57: import org.eclipse.emfforms.spi.spreadsheet.core.converter.EMFFormsConverterException;
58: import org.eclipse.emfforms.spi.spreadsheet.core.converter.EMFFormsSpreadsheetValueConverter;
59: import org.eclipse.emfforms.spi.spreadsheet.core.converter.EMFFormsSpreadsheetValueConverterRegistry;
60: import org.eclipse.emfforms.spi.spreadsheet.core.error.model.ErrorFactory;
61: import org.eclipse.emfforms.spi.spreadsheet.core.error.model.SettingLocation;
62: import org.eclipse.emfforms.spi.spreadsheet.core.error.model.Severity;
63: import org.eclipse.emfforms.spi.spreadsheet.core.error.model.SpreadsheetImportResult;
64: import org.eclipse.emfforms.spi.spreadsheet.core.transfer.EMFFormsSpreadsheetImporter;
65: import org.osgi.framework.BundleContext;
66: import org.osgi.framework.FrameworkUtil;
67: import org.osgi.framework.ServiceReference;
68:
69: /**
70: * Implementation of the {@link EMFFormsSpreadsheetImporter}.
71: *
72: * @author Eugen Neufeld
73: */
74: public class EMFFormsSpreadsheetImporterImpl implements EMFFormsSpreadsheetImporter {
75:
76:         private static final String IGNORE_SHEET = "Ignore Sheet"; //$NON-NLS-1$
77:         private EMFFormsDomainExpander domainExpander;
78:
79:         @Override
80:         public SpreadsheetImportResult importSpreadsheet(Workbook workbook, EClass eClass) {
81:                 final BundleContext bundleContext = FrameworkUtil.getBundle(EMFFormsSpreadsheetImporterImpl.class)
82:                         .getBundleContext();
83:                 final ServiceReference<EMFFormsDomainExpander> serviceReference = bundleContext
84:                         .getServiceReference(EMFFormsDomainExpander.class);
85:                 domainExpander = bundleContext.getService(serviceReference);
86:
87:                 final SpreadsheetImportResult result = readData(workbook, eClass);
88:
89:                 domainExpander = null;
90:                 bundleContext.ungetService(serviceReference);
91:
92:                 return result;
93:         }
94:
95:         private SpreadsheetImportResult readData(Workbook workbook, EClass eClass) {
96:                 final SpreadsheetImportResult result = ErrorFactory.eINSTANCE.createSpreadsheetImportResult();
97:                 final ResourceSet rs = new ResourceSetImpl();
98:                 final MigrationInformation information = new MigrationInformation();
99:                 final AdapterFactoryEditingDomain domain = new AdapterFactoryEditingDomain(
100:                         new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE),
101:                         new BasicCommandStack(), rs);
102:                 rs.eAdapters().add(new AdapterFactoryEditingDomain.EditingDomainProvider(domain));
103:                 final Resource resource = rs.createResource(URI.createURI("VIRTUAL_URI")); //$NON-NLS-1$
104:
105:                 final Map<String, Map<Integer, Integer>> mapIdToSheetIdWithRowId = parseIds(workbook, result);
106:                 final Map<String, VDomainModelReference> sheetColumnToDMRMap = new LinkedHashMap<String, VDomainModelReference>();
107:                 final Map<VDomainModelReference, EMFFormsSpreadsheetValueConverter> converter = new LinkedHashMap<VDomainModelReference, EMFFormsSpreadsheetValueConverter>();
108:                 final List<EObject> importedEObjects = new ArrayList<EObject>(mapIdToSheetIdWithRowId.size());
109:                 for (final String eObjectId : mapIdToSheetIdWithRowId.keySet()) {
110:                         final Map<Integer, Integer> sheetIdToRowId = mapIdToSheetIdWithRowId.get(eObjectId);
111:                         final EObject eObject = EcoreUtil.create(eClass);
112:                         resource.getContents().add(eObject);
113:                         for (final Integer sheetId : sheetIdToRowId.keySet()) {
114:                                 final Sheet sheet = workbook.getSheetAt(sheetId);
115:                                 final Row labelRow = sheet.getRow(0);
116:                                 final Row row = sheet.getRow(sheetIdToRowId.get(sheetId));
117:                                 extractRowInformation(labelRow, row, eObject, result, sheet.getSheetName(), sheetId,
118:                                         sheetColumnToDMRMap, converter, information);
119:                         }
120:                         importedEObjects.add(eObject);
121:                 }
122:                 result.getImportedEObjects().addAll(importedEObjects);
123:                 return result;
124:         }
125:
126:         /**
127:          * Extracts the information from the row and sets the value on the given root EObject.
128:          */
129:         // BEGIN COMPLEX CODE
130:         private void extractRowInformation(final Row dmrRow, final Row eObjectRow, final EObject eObject,
131:                 SpreadsheetImportResult errorReports, String sheetname, int sheetId,
132:                 Map<String, VDomainModelReference> sheetColumnToDMRMap,
133:                 Map<VDomainModelReference, EMFFormsSpreadsheetValueConverter> converterMap,
134:                 MigrationInformation information) {
135:                 for (int columnId = 1; columnId < dmrRow.getLastCellNum(); columnId++) {
136:                         final String sheetColId = sheetId + "_" + columnId; //$NON-NLS-1$
137:                         final Cell cell = dmrRow.getCell(columnId);
138:                         if (!sheetColumnToDMRMap.containsKey(sheetColId)) {
139:                                 final VDomainModelReference dmr = getDomainModelReference(cell, errorReports, eObject, sheetname,
140:                                         columnId, information);
141:                                 sheetColumnToDMRMap.put(sheetColId, dmr);
142:                         }
143:                         final VDomainModelReference dmr = sheetColumnToDMRMap.get(sheetColId);
144:                         if (dmr == null) {
145:                                 continue;
146:                         }
147:
148:                         /* resolve dmr */
149:                         try {
150:                                 resolveDMR(dmr, eObject);
151:                         } catch (final EMFFormsExpandingFailedException ex) {
152:                                 errorReports.reportError(
153:                                         Severity.ERROR, LocalizationServiceHelper.getString(EMFFormsSpreadsheetImporterImpl.class,
154:                                                 "ImportError_DMRResolvementFailed"), //$NON-NLS-1$
155:                                         ErrorFactory.eINSTANCE.createEMFLocation(eObject,
156:                                                 ErrorFactory.eINSTANCE.createDMRLocation(dmr)),
157:                                         ErrorFactory.eINSTANCE.createSheetLocation(sheetname, columnId, 0,
158:                                                 getStringCellValue(cell, errorReports, sheetname, columnId)));
159:                                 continue;
160:                         }
161:
162:                         /* initiate databinding */
163:                         Setting setting;
164:                         try {
165:                                 setting = getSetting(dmr, eObject);
166:                         } catch (final DatabindingFailedException ex) {
167:                                 errorReports.reportError(
168:                                         Severity.ERROR,
169:                                         LocalizationServiceHelper.getString(EMFFormsSpreadsheetImporterImpl.class,
170:                                                 MessageFormat.format("ImportError_DatabindingFailed", ex.getMessage())), //$NON-NLS-1$
171:                                         ErrorFactory.eINSTANCE.createEMFLocation(eObject,
172:                                                 ErrorFactory.eINSTANCE.createDMRLocation(dmr)),
173:                                         ErrorFactory.eINSTANCE.createSheetLocation(sheetname, columnId, 0,
174:                                                 getStringCellValue(cell, errorReports, sheetname, columnId)));
175:                                 continue;
176:                         }
177:
178:                         /* access value converter */
179:                         if (!converterMap.containsKey(dmr)) {
180:                                 try {
181:                                         final EMFFormsSpreadsheetValueConverter converter = getValueConverter(dmr, eObject);
182:                                         converterMap.put(dmr, converter);
183:                                 } catch (final EMFFormsConverterException ex) {
184:                                         errorReports.reportError(
185:                                                 Severity.ERROR, LocalizationServiceHelper.getString(EMFFormsSpreadsheetImporterImpl.class,
186:                                                         "ImportError_NoValueConverter"), //$NON-NLS-1$
187:                                                 ErrorFactory.eINSTANCE.createEMFLocation(eObject,
188:                                                         ErrorFactory.eINSTANCE.createDMRLocation(dmr)),
189:                                                 ErrorFactory.eINSTANCE.createSheetLocation(sheetname, columnId, 0,
190:                                                         getStringCellValue(cell, errorReports, sheetname, columnId)));
191:                                         continue;
192:                                 }
193:                         }
194:                         final EMFFormsSpreadsheetValueConverter converter = converterMap.get(dmr);
195:
196:                         final EStructuralFeature feature = setting.getEStructuralFeature();
197:
198:                         /* access cell with value */
199:                         Cell rowCell;
200:                         if (feature.isUnsettable()) {
201:                                 rowCell = eObjectRow.getCell(columnId, Row.RETURN_NULL_AND_BLANK);
202:                         } else {
203:                                 rowCell = eObjectRow.getCell(columnId, Row.CREATE_NULL_AS_BLANK);
204:                         }
205:
206:                         if (rowCell == null) {
207:                                 /* no error -> unsettable feature */
208:                                 errorReports.getSettingToSheetMap()
209:                                         .add(ErrorFactory.eINSTANCE.createSettingToSheetMapping(
210:                                                 createSettingLocation(setting),
211:                                                 ErrorFactory.eINSTANCE.createSheetLocation(sheetname, columnId, eObjectRow.getRowNum(),
212:                                                         getStringCellValue(cell, errorReports, sheetname, columnId))));
213:                                 continue;
214:                         }
215:
216:                         /* convert value */
217:                         Object convertedValue;
218:                         try {
219:                                 convertedValue = converter.getCellValue(rowCell, feature);
220:                         } catch (final EMFFormsConverterException ex) {
221:                                 errorReports.reportError(
222:                                         Severity.ERROR,
223:                                         MessageFormat.format(
224:                                                 LocalizationServiceHelper.getString(EMFFormsSpreadsheetImporterImpl.class,
225:                                                         "ImportError_ValueConversionFailed"), //$NON-NLS-1$
226:                                                 ex.getMessage()),
227:                                         ErrorFactory.eINSTANCE.createEMFLocation(eObject,
228:                                                 createSettingLocation(setting),
229:                                                 ErrorFactory.eINSTANCE.createDMRLocation(dmr)),
230:                                         ErrorFactory.eINSTANCE.createSheetLocation(sheetname, columnId, eObjectRow.getRowNum(),
231:                                                 getStringCellValue(cell, errorReports, sheetname, columnId)));
232:                                 continue;
233:                         }
234:
235:                         /* check converted value */
236:                         if (convertedValue != null) {
237:                                 if (!checkTypes(feature, convertedValue)) {
238:                                         errorReports.reportError(
239:                                                 Severity.ERROR,
240:                                                 LocalizationServiceHelper.getString(EMFFormsSpreadsheetImporterImpl.class,
241:                                                         "ImportError_InvalidType"), //$NON-NLS-1$
242:                                                 ErrorFactory.eINSTANCE.createEMFLocation(eObject,
243:                                                         createSettingLocation(setting),
244:                                                         ErrorFactory.eINSTANCE.createDMRLocation(dmr)),
245:                                                 ErrorFactory.eINSTANCE.createSheetLocation(sheetname, columnId, eObjectRow.getRowNum(),
246:                                                         getStringCellValue(cell, errorReports, sheetname, columnId)));
247:                                         continue;
248:                                 }
249:                         }
250:
251:                         if (convertedValue == null && feature.isUnsettable()) {
252:                                 setting.unset();
253:                         } else {
254:                                 /* set value */
255:                                 setting.set(convertedValue);
256:                         }
257:
258:                         errorReports.getSettingToSheetMap()
259:                                 .add(ErrorFactory.eINSTANCE.createSettingToSheetMapping(
260:                                         createSettingLocation(setting),
261:                                         ErrorFactory.eINSTANCE.createSheetLocation(sheetname, columnId, eObjectRow.getRowNum(),
262:                                                 getStringCellValue(cell, errorReports, sheetname, columnId))));
263:                 }
264:         }
265:
266:         private VDomainModelReference getDomainModelReference(Cell cell, SpreadsheetImportResult errorReports,
267:                 EObject eObject, String sheetname, int columnId, MigrationInformation information) {
268:                 /* get dmr comment */
269:                 if (cell == null) {
270:                         errorReports.reportError(
271:                                 Severity.ERROR, LocalizationServiceHelper.getString(EMFFormsSpreadsheetImporterImpl.class,
272:                                         "ImportError_LabelCellDeleted"), //$NON-NLS-1$
273:                                 ErrorFactory.eINSTANCE.createEMFLocation(eObject),
274:                                 ErrorFactory.eINSTANCE.createSheetLocation(sheetname, columnId, 0, "NO CELL")); //$NON-NLS-1$
275:                         return null;
276:                 }
277:                 final Comment cellComment = cell.getCellComment();
278:                 if (cellComment == null) {
279:                         errorReports.reportError(
280:                                 Severity.ERROR, LocalizationServiceHelper.getString(EMFFormsSpreadsheetImporterImpl.class,
281:                                         "ImportError_CommentDeleted"), //$NON-NLS-1$
282:                                 ErrorFactory.eINSTANCE.createEMFLocation(eObject),
283:                                 ErrorFactory.eINSTANCE.createSheetLocation(sheetname, columnId, 0,
284:                                         getStringCellValue(cell, errorReports, sheetname, columnId)));
285:                         return null;
286:                 }
287:                 final String serializedDMR = cellComment.getString().getString();
288:                 if (serializedDMR == null || serializedDMR.isEmpty()) {
289:                         errorReports.reportError(
290:                                 Severity.ERROR,
291:                                 LocalizationServiceHelper.getString(EMFFormsSpreadsheetImporterImpl.class, "ImportError_CommentEmpty"), //$NON-NLS-1$
292:                                 ErrorFactory.eINSTANCE.createEMFLocation(eObject),
293:                                 ErrorFactory.eINSTANCE.createSheetLocation(sheetname, columnId, 0,
294:                                         getStringCellValue(cell, errorReports, sheetname, columnId)));
295:                         return null;
296:                 }
297:
298:                 /* deserialize dmr */
299:
300:                 try {
301:                         return deserializeDMR(serializedDMR, information);
302:                 } catch (final IOException ex1) {
303:                         errorReports.reportError(
304:                                 Severity.ERROR,
305:                                 LocalizationServiceHelper.getString(EMFFormsSpreadsheetImporterImpl.class,
306:                                         "ImportError_DMRDeserializationFailed"), //$NON-NLS-1$
307:                                 ErrorFactory.eINSTANCE.createEMFLocation(eObject),
308:                                 ErrorFactory.eINSTANCE.createSheetLocation(sheetname, columnId, 0,
309:                                         getStringCellValue(cell, errorReports, sheetname, columnId)));
310:                         return null;
311:                 }
312:
313:         }
314:
315:         // END COMPLEX CODE
316:
317:         /**
318:          * Checks whether the converted value can be set on the feature.
319:          */
320:         private boolean checkTypes(final EStructuralFeature feature, final Object convertedValue) {
321:                 final Class<?> featureType = feature.getEType().getInstanceClass();
322:
323:                 if (convertedValue == null) {
324:                         return !featureType.isPrimitive();
325:                 }
326:
327:                 final Class<? extends Object> valueType = convertedValue.getClass();
328:
329:                 if (feature.isMany()) {
330:                         if (Collection.class.isInstance(convertedValue)) {
331:                                 final Collection<?> collection = Collection.class.cast(convertedValue);
332:                                 for (final Object object : collection) {
333:                                         if (!checkTypes(feature, object)) {
334:                                                 return false;
335:                                         }
336:                                 }
337:                                 return true;
338:                         }
339:                         /* else continue with regular checks */
340:                 }
341:
342:                 if (featureType.isPrimitive() && !valueType.isPrimitive()) {
343:                         final Class<?> primitiveClass = getPrimitiveClass(valueType);
344:                         if (primitiveClass == null) {
345:                                 return false;
346:                         }
347:                         return featureType.isAssignableFrom(primitiveClass);
348:                 }
349:
350:                 if (!featureType.isPrimitive() && valueType.isPrimitive()) {
351:                         final Class<?> primitiveClass = getPrimitiveClass(featureType);
352:                         if (primitiveClass == null) {
353:                                 return false;
354:                         }
355:                         return primitiveClass.isAssignableFrom(valueType);
356:                 }
357:
358:                 return featureType.isAssignableFrom(valueType);
359:         }
360:
361:         private Class<?> getPrimitiveClass(Class<?> clazz) {
362:                 try {
363:                         return (Class<?>) clazz.getField("TYPE").get(null); //$NON-NLS-1$
364:                 } catch (final IllegalArgumentException ex) {
365:                 } catch (final IllegalAccessException ex) {
366:                 } catch (final NoSuchFieldException ex) {
367:                 } catch (final SecurityException ex) {
368:                 }
369:                 return null;
370:         }
371:
372:         private SettingLocation createSettingLocation(Setting setting) {
373:                 return ErrorFactory.eINSTANCE.createSettingLocation(setting.getEObject(), setting.getEStructuralFeature());
374:         }
375:
376:         private void resolveDMR(VDomainModelReference dmr, EObject eObject) throws EMFFormsExpandingFailedException {
377:                 domainExpander.prepareDomainObject(dmr, eObject);
378:         }
379:
380:         /**
381:          * Returns a Map from EObject-ID to Sheet-ID to Row-ID.
382:          */
383:         private Map<String, Map<Integer, Integer>> parseIds(Workbook workbook, SpreadsheetImportResult errorReports) {
384:                 final Map<String, Map<Integer, Integer>> result = new LinkedHashMap<String, Map<Integer, Integer>>();
385:
386:                 for (int sheetId = 0; sheetId < workbook.getNumberOfSheets(); sheetId++) {
387:                         final Sheet sheet = workbook.getSheetAt(sheetId);
388:                         final Row labelRow = sheet.getRow(0);
389:                         if (labelRow == null) {
390:                                 errorReports.reportError(
391:                                         Severity.ERROR, MessageFormat.format(
392:                                                 LocalizationServiceHelper.getString(EMFFormsSpreadsheetImporterImpl.class,
393:                                                         "ImportError_SheetEmpty"), //$NON-NLS-1$
394:                                                 sheet.getSheetName()),
395:                                         ErrorFactory.eINSTANCE.createSheetLocation(workbook.getSheetName(sheetId), 0, 0, "NO CELL")); //$NON-NLS-1$
396:                                 continue;
397:                         }
398:                         final Cell idColumnLabelCell = labelRow.getCell(0, Row.CREATE_NULL_AS_BLANK);
399:                         final Comment cellComment = idColumnLabelCell.getCellComment();
400:                         if (cellComment != null && cellComment.getString() != null
401:                                 && IGNORE_SHEET.equals(cellComment.getString().getString())) {
402:                                 continue;
403:                         }
404:                         final String idColumnLabel = getStringCellValue(idColumnLabelCell, errorReports,
405:                                 workbook.getSheetName(sheetId), 0);
406:                         if (!EMFFormsIdProvider.ID_COLUMN.equals(idColumnLabel)) {
407:                                 /* ID Column is missing. We have to ignore this sheet */
408:                                 errorReports.reportError(
409:                                         Severity.ERROR, MessageFormat.format(
410:                                                 LocalizationServiceHelper.getString(EMFFormsSpreadsheetImporterImpl.class,
411:                                                         "ImportError_FirstColumnWrong"), //$NON-NLS-1$
412:                                                 EMFFormsIdProvider.ID_COLUMN, idColumnLabel),
413:                                         ErrorFactory.eINSTANCE.createSheetLocation(workbook.getSheetName(sheetId), 0, 0, "NO CELL")); //$NON-NLS-1$
414:                                 continue;
415:                         }
416:                         for (int rowId = 3; rowId <= sheet.getLastRowNum(); rowId++) {
417:                                 final Row row = sheet.getRow(rowId);
418:                                 if (row == null || isRowEmpty(row)) {
419:                                         errorReports.reportError(
420:                                                 Severity.INFO, LocalizationServiceHelper.getString(EMFFormsSpreadsheetImporterImpl.class,
421:                                                         "ImportError_EmptyRow"), //$NON-NLS-1$
422:                                                 ErrorFactory.eINSTANCE.createSheetLocation(workbook.getSheetName(sheetId), 0, rowId,
423:                                                         EMFFormsIdProvider.ID_COLUMN));
424:                                         continue;
425:                                 }
426:                                 final String eObjectId = getStringCellValue(row.getCell(0, Row.CREATE_NULL_AS_BLANK), errorReports,
427:                                         workbook.getSheetName(sheetId), 0, rowId);
428:                                 if (eObjectId == null || eObjectId.isEmpty()) {
429:                                         /* EObject id deleted */
430:                                         errorReports.reportError(
431:                                                 Severity.ERROR, LocalizationServiceHelper.getString(EMFFormsSpreadsheetImporterImpl.class,
432:                                                         "ImportError_NoEObjectID"), //$NON-NLS-1$
433:                                                 ErrorFactory.eINSTANCE.createSheetLocation(workbook.getSheetName(sheetId), 0, rowId,
434:                                                         EMFFormsIdProvider.ID_COLUMN));
435:                                         continue;
436:                                 }
437:                                 if (!result.containsKey(eObjectId)) {
438:                                         result.put(eObjectId, new LinkedHashMap<Integer, Integer>());
439:                                 }
440:                                 // each sheetid should only be mapped once to each eobjectid
441:                                 if (result.get(eObjectId).containsKey(sheetId)) {
442:                                         /* duplicate EObject ID */
443:                                         errorReports.reportError(
444:                                                 Severity.ERROR,
445:                                                 LocalizationServiceHelper.getString(EMFFormsSpreadsheetImporterImpl.class,
446:                                                         "ImportError_DuplicateEObjectID"), //$NON-NLS-1$
447:                                                 ErrorFactory.eINSTANCE.createSheetLocation(workbook.getSheetName(sheetId), 0, rowId,
448:                                                         EMFFormsIdProvider.ID_COLUMN));
449:                                         continue;
450:                                 }
451:                                 result.get(eObjectId).put(sheetId, rowId);
452:                         }
453:                 }
454:                 return result;
455:         }
456:
457:         private Setting getSetting(VDomainModelReference dmr, EObject eObject)
458:                 throws DatabindingFailedException {
459:                 final BundleContext bundleContext = FrameworkUtil.getBundle(getClass()).getBundleContext();
460:                 final ServiceReference<EMFFormsDatabindingEMF> serviceReference = bundleContext
461:                         .getServiceReference(EMFFormsDatabindingEMF.class);
462:                 final EMFFormsDatabindingEMF emfFormsDatabinding = bundleContext.getService(serviceReference);
463:                 return emfFormsDatabinding.getSetting(dmr, eObject);
464:         }
465:
466:         private EMFFormsSpreadsheetValueConverter getValueConverter(VDomainModelReference dmr, EObject eObject)
467:                 throws EMFFormsConverterException {
468:                 final BundleContext bundleContext = FrameworkUtil.getBundle(getClass()).getBundleContext();
469:                 final ServiceReference<EMFFormsSpreadsheetValueConverterRegistry> serviceReference = bundleContext
470:                         .getServiceReference(EMFFormsSpreadsheetValueConverterRegistry.class);
471:                 final EMFFormsSpreadsheetValueConverterRegistry emfFormsDatabinding = bundleContext
472:                         .getService(serviceReference);
473:                 return emfFormsDatabinding.getConverter(eObject, dmr);
474:         }
475:
476:         private VDomainModelReference deserializeDMR(String serializedDMR, MigrationInformation information)
477:                 throws IOException {
478:                 if (ViewModelMigratorUtil.getStringViewModelMigrator() != null) {
479:                         try {
480:                                 serializedDMR = migrateIfNeeded(serializedDMR, information);
481:                         } catch (final ViewModelMigrationException ex) {
482:                                 throw new IOException(ex);
483:                         }
484:                 }
485:                 final ResourceSet rs = new ResourceSetImpl();
486:                 final Resource resource = rs.createResource(URI.createURI("VIRTAUAL_URI")); //$NON-NLS-1$
487:
488:                 final ReadableInputStream is = new ReadableInputStream(serializedDMR, "UTF-8"); //$NON-NLS-1$
489:                 resource.load(is, null);
490:                 return (VDomainModelReference) resource.getContents().get(0);
491:         }
492:
493:         private String migrateIfNeeded(String serializedDMR, MigrationInformation information)
494:                 throws ViewModelMigrationException {
495:                 final List<String> namespaceURIs = StringViewModelMigratorUtil.getNamespaceURIs(serializedDMR);
496:
497:                 final MigrationInformation.State migrationState = information.isMigrationNeeded(namespaceURIs);
498:
499:                 if (migrationState == State.ok) {
500:                         return serializedDMR;
501:                 }
502:
503:                 final StringViewModelMigrator migrator = ViewModelMigratorUtil.getStringViewModelMigrator();
504:
505:                 if (migrationState == State.unknown) {
506:                         if (migrator.checkMigration(serializedDMR)) {
507:                                 information.noMigrationNeeded(namespaceURIs);
508:                                 return serializedDMR;
509:                         }
510:                         information.migrationNeeded(namespaceURIs);
511:                 }
512:
513:                 return migrator.performMigration(serializedDMR);
514:         }
515:
516:         private String getStringCellValue(Cell cell, SpreadsheetImportResult errorReports, String sheetName, int columnId) {
517:                 return getStringCellValue(cell, errorReports, sheetName, columnId, 0);
518:         }
519:
520:         private String getStringCellValue(Cell cell, SpreadsheetImportResult errorReports, String sheetName, int columnId,
521:                 int rowId) {
522:                 try {
523:                         return cell.getStringCellValue();
524:                 } catch (final IllegalStateException ex) {
525:                         errorReports.reportError(
526:                                 Severity.ERROR, ex.getMessage(),
527:                                 ErrorFactory.eINSTANCE.createEMFLocation(),
528:                                 ErrorFactory.eINSTANCE.createSheetLocation(sheetName, columnId, rowId, "")); //$NON-NLS-1$
529:                         return ""; //$NON-NLS-1$
530:                 }
531:         }
532:
533:         /**
534:          * Helper class which caches the required information of the migration state for the used NS-URIs.
535:          *
536:          * @author Johannes Faltermeier
537:          *
538:          */
539:         static class MigrationInformation {
540:                 private final Set<Set<String>> migrationNeeded = new LinkedHashSet<Set<String>>();
541:                 private final Set<Set<String>> noMigrationNeeded = new LinkedHashSet<Set<String>>();
542:
543:                 /**
544:                  * Whether a migration is needed for the given uris.
545:                  *
546:                  * @param namespaceURIs the uris
547:                  * @return the state
548:                  */
549:                 State isMigrationNeeded(List<String> namespaceURIs) {
550:                         final Set<String> set = new LinkedHashSet<String>(namespaceURIs);
551:                         if (noMigrationNeeded.contains(set)) {
552:                                 return State.ok;
553:                         }
554:                         if (migrationNeeded.contains(set)) {
555:                                 return State.migrate;
556:                         }
557:                         return State.unknown;
558:                 }
559:
560:                 /**
561:                  * Updates the cached migration information.
562:                  *
563:                  * @param namespaceURIs the given set of nsuris for which a migration is required
564:                  */
565:                 void migrationNeeded(List<String> namespaceURIs) {
566:                         final Set<String> set = Collections.unmodifiableSet(new LinkedHashSet<String>(namespaceURIs));
567:                         migrationNeeded.add(set);
568:                 }
569:
570:                 /**
571:                  * Updates the cached migration information.
572:                  *
573:                  * @param namespaceURIs the given set of nsuris for which no migration is required
574:                  */
575:                 void noMigrationNeeded(List<String> namespaceURIs) {
576:                         final Set<String> set = Collections.unmodifiableSet(new LinkedHashSet<String>(namespaceURIs));
577:                         noMigrationNeeded.add(set);
578:                 }
579:
580:                 /**
581:                  * Migration state.
582:                  *
583:                  * @author Johannes Faltermeier
584:                  *
585:                  */
586:                 enum State {
587:                         /**
588:                          * Based on the cached information a migration is needed.
589:                          */
590:                         migrate,
591:
592:                         /**
593:                          * Based on the cached information no migration is needed.
594:                          */
595:                         ok,
596:
597:                         /**
598:                          * No cached information about the migration state.
599:                          */
600:                         unknown
601:                 }
602:
603:         }
604:
605:         private static boolean isRowEmpty(Row row) {
606:                 for (int c = row.getFirstCellNum(); c < row.getLastCellNum(); c++) {
607:                         final Cell cell = row.getCell(c);
608:                         if (cell != null && cell.getCellType() != Cell.CELL_TYPE_BLANK) {
609:                                 return false;
610:                         }
611:                 }
612:                 return true;
613:         }
614: }