This how I persist two EMF objects (a static shelf
and a dynamic md5
) into a zipped binary file:
static void save(Shelf shelf, String file, EClass md5class) throws Exception {
EObject md5 = stringToMD5EObject("0x0abc", md5class);
Resource resource = createResource(file, md5class.getEPackage(), shelf.eClass().getEPackage());
resource.getContents().add(md5);
resource.getContents().add(shelf);
resource.save(options());
}
static Resource createResource(String file, EPackage... packages) {
ResourceSet resourceSet = new ResourceSetImpl();
Resource.Factory factory = uri -> new BinaryResourceImpl(uri);
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("bin", factory);
for (EPackage p : packages) resourceSet.getPackageRegistry().put(p.getNsURI(), p);
URI fileURI = URI.createFileURI(new File(file).getAbsolutePath());
return resourceSet.createResource(fileURI);
}
static Map<String, Object> options() {
return Collections.singletonMap(BinaryResourceImpl.OPTION_ZIP, Boolean.TRUE);
}
The question is how to configure the resource if I'm given an already open OutputStream, that is without no access whatsoever to the filename?
Here's a solution for future reference:
static {
options = Collections.singletonMap(BinaryResourceImpl.OPTION_ZIP, true);
}
public void save(OutputStream outputStream, EObject ... eObject) throws Exception {
Resource resource = createResource(Arrays.stream(eObject).map(x -> x.eClass().getEPackage()));
Arrays.stream(eObject).forEach(resource.getContents()::add);
resource.save(outputStream, options);
}
public EList<EObject> load(InputStream inputStream, EPackage ... packages) throws Exception {
Resource resource = createResource(Arrays.stream(packages));
resource.load(inputStream, options);
return resource.getContents();
}
private Resource createResource(Stream<EPackage> packages) {
ResourceSet resourceSet = new ResourceSetImpl();
Resource.Factory resourceFactory = __ -> new BinaryResourceImpl();
resourceSet.getResourceFactoryRegistry().getContentTypeToFactoryMap().put("*", resourceFactory);
packages.forEach(p -> resourceSet.getPackageRegistry().put(p.getNsURI(), p));
return resourceSet.createResource(null);
}