RuntimeModelParserImpl implements RuntimeModelParser { RuntimeModel retrieveRuntimeModel(String modelId, InputStream is) throws IOException { List<DataSetContent> datasetContents = new ArrayList<>(); List<LayoutTemplate> layoutTemplates = new ArrayList<>(); Optional<String> navTreeOp = Optional.empty(); try (ZipInputStream zis = new ZipInputStream(is)) { ZipEntry entry; while ((entry = zis.getNextEntry()) != null) { if (entry.isDirectory()) { continue; } String entryName = entry.getName(); if (entryName.startsWith(DATASET_DEF_PREFIX)) { datasetContents.add(retrieveDataSetContent(entry, zis)); } if (entryName.endsWith(PERSPECTIVE_SUFFIX)) { layoutTemplates.add(retrieveLayoutTemplate(zis)); } if (entryName.equalsIgnoreCase(NAVIGATION_FILE)) { navTreeOp = Optional.of(nextEntryContentAsString(zis)); } if (entryName.startsWith(COMPONENTS_EXPORT_PATH)) { extractComponentFile(modelId, zis, entry.getName()); } } } if (options.isMultipleImport()) { if (options.isDatasetPartition()) { datasetContents.forEach(ds -> ds.setId(transformId(modelId, ds.getId()))); } layoutTemplates.forEach(lt -> partitionLayoutTemplate(modelId, lt)); } if (!datasetContents.isEmpty()) { newDataSetContentEvent.fire(new NewDataSetContentEvent(modelId, datasetContents)); } NavTree navTree = runtimeNavigationBuilder.build(navTreeOp, layoutTemplates); return new RuntimeModel(navTree, layoutTemplates); }  @Override RuntimeModel parse(String modelId, InputStream is);  }
@Test public void testEmptyImport() throws IOException { when(navigationBuilder.build(any(), any())).thenReturn(new NavTreeBuilder().build()); InputStream emptyImport = this.getClass().getResourceAsStream("/empty.zip"); RuntimeModel runtimeModel = parser.retrieveRuntimeModel("", emptyImport); verify(newDataSetContentEventSource, times(0)).fire(any()); assertTrue(runtimeModel.getLayoutTemplates().isEmpty()); assertTrue(runtimeModel.getNavTree().getRootItems().isEmpty()); }