package eu.europeana.cloud.service.mcs.inmemory; import eu.europeana.cloud.common.model.File; import eu.europeana.cloud.common.model.Record; import eu.europeana.cloud.common.model.Representation; import eu.europeana.cloud.service.mcs.exception.CannotModifyPersistentRepresentationException; import eu.europeana.cloud.service.mcs.exception.FileNotExistsException; import eu.europeana.cloud.service.mcs.exception.RecordNotExistsException; import eu.europeana.cloud.service.mcs.exception.RepresentationNotExistsException; import eu.europeana.cloud.service.mcs.exception.VersionNotExistsException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.ListIterator; import java.util.Map; import org.springframework.stereotype.Repository; /** * InMemoryRecordDAO */ @Repository public class InMemoryRecordDAO { // globalId -> (representationName -> representationVersions) private Map<String, Map<String, List<Representation>>> records = new HashMap<>(); public Record getRecord(String globalId) throws RecordNotExistsException { Map<String, List<Representation>> representations = records.get(globalId); if (representations == null) { throw new RecordNotExistsException(globalId); } Record record = new Record(); record.setCloudId(globalId); List<Representation> representationInfos = new ArrayList<>(); record.setRepresentations(representationInfos); for (Map.Entry<String, List<Representation>> representation : representations.entrySet()) { representationInfos.add(getLatestRepresentation(representation.getValue())); } return record; } public void deleteRecord(String globalId) throws RecordNotExistsException { if (records.containsKey(globalId)) { records.remove(globalId); } else { throw new RecordNotExistsException(globalId); } } public List<Representation> findRepresentations(String providerId, String schema) { List<Representation> representations = new ArrayList<>(); for (Map<String, List<Representation>> representationNameToVersionList : records.values()) { for (List<Representation> repVersionList : representationNameToVersionList.values()) { Representation latestVersion = getLatestRepresentation(repVersionList); boolean providerMatch = providerId == null || latestVersion.getDataProvider().equals(providerId); boolean schemaMatch = schema == null || latestVersion.getRepresentationName().equals(schema); if (providerMatch && schemaMatch) { representations.add(latestVersion); } } } return representations; } private Representation getLatestPersistentRepresentation(List<Representation> versions) { for (int i = versions.size() - 1; i >= 0; i--) { Representation rep = versions.get(i); if (rep.isPersistent()) { return copy(rep); } } return null; } private Representation getLatestRepresentation(List<Representation> versions) { Representation latestPersistent = getLatestPersistentRepresentation(versions); if (latestPersistent == null) { return copy(versions.get(versions.size() - 1)); } else { return latestPersistent; } } private Representation copy(Representation rep) { Representation copy = new Representation(); copy.setDataProvider(rep.getDataProvider()); copy.setFiles(new ArrayList<>(rep.getFiles())); copy.setPersistent(rep.isPersistent()); copy.setCloudId(rep.getCloudId()); copy.setRepresentationName(rep.getRepresentationName()); copy.setVersion(rep.getVersion()); return copy; } public void deleteRepresentation(String globalId, String schema) throws RepresentationNotExistsException { Map<String, List<Representation>> representations = records.get(globalId); if (representations == null) { throw new RepresentationNotExistsException(); } if (representations.containsKey(schema)) { representations.remove(schema); } else { throw new RepresentationNotExistsException(); } } public Representation createRepresentation(String globalId, String schema, String providerId) { Map<String, List<Representation>> representations = records.get(globalId); if (representations == null) { representations = new HashMap<>(); records.put(globalId, representations); } List<Representation> representationVersions = representations.get(schema); if (representationVersions == null) { representationVersions = new ArrayList<>(); representations.put(schema, representationVersions); } Representation rep = new Representation(); rep.setCloudId(globalId); rep.setPersistent(false); rep.setDataProvider(providerId); rep.setRepresentationName(schema); rep.setFiles(new ArrayList<File>()); String version = generateNewVersionNumber(representationVersions, false); rep.setVersion(version); representationVersions.add(rep); return rep; } // persistentVersion: \d+ // tempVersion: \d+[.]PRE-\d+ private String generateNewVersionNumber(List<Representation> versions, boolean persistent) { if (versions.isEmpty()) { if (persistent) { return "1"; } else { return "1.PRE-1"; } } Representation latestRepresentation = versions.get(versions.size() - 1); boolean latestIsPersistent = latestRepresentation.isPersistent(); if (latestIsPersistent && persistent) { return Integer.toString(Integer.parseInt(latestRepresentation.getVersion()) + 1); } else if (latestIsPersistent && !persistent) { return Integer.toString(Integer.parseInt(latestRepresentation.getVersion()) + 1) + ".PRE-1"; } else if (persistent) { return latestRepresentation.getVersion().substring(0, latestRepresentation.getVersion().indexOf(".")); } else { String[] parts = latestRepresentation.getVersion().split("-"); return parts[0] + "-" + (Integer.parseInt(parts[1]) + 1); } } public Representation getRepresentation(String globalId, String schema, String version) throws RepresentationNotExistsException, VersionNotExistsException { Map<String, List<Representation>> representations = records.get(globalId); if (representations == null) { throw new RepresentationNotExistsException("No representation for " + globalId); } List<Representation> representationVersions = representations.get(schema); if (representationVersions == null) { throw new RepresentationNotExistsException(); } if (version == null) { return getLatestRepresentation(representationVersions); } else { Representation rep = getByVersion(representationVersions, version); if (rep == null) { throw new VersionNotExistsException(); } else { return copy(rep); } } } public void deleteRepresentation(String globalId, String schema, String version) throws RepresentationNotExistsException, VersionNotExistsException, CannotModifyPersistentRepresentationException { Map<String, List<Representation>> representations = records.get(globalId); if (representations == null) { throw new RepresentationNotExistsException(globalId); } List<Representation> representationVersions = representations.get(schema); if (representationVersions == null) { throw new RepresentationNotExistsException(); } Representation repInVersion = getByVersion(representationVersions, version); if (repInVersion == null) { throw new VersionNotExistsException(); } else if (repInVersion.isPersistent()) { throw new CannotModifyPersistentRepresentationException(); } else { representationVersions.remove(repInVersion); } } private Representation getByVersion(List<Representation> versions, String version) { for (Representation rep : versions) { if (rep.getVersion().equals(version)) { return rep; } } return null; } public Representation persistRepresentation(String globalId, String schema, String version) throws RepresentationNotExistsException, VersionNotExistsException, CannotModifyPersistentRepresentationException { Map<String, List<Representation>> representations = records.get(globalId); if (representations == null) { throw new RepresentationNotExistsException(globalId); } List<Representation> representationVersions = representations.get(schema); if (representationVersions == null) { throw new RepresentationNotExistsException(); } Representation repVersion = getByVersion(representationVersions, version); if (repVersion == null) { throw new VersionNotExistsException(); } else if (repVersion.isPersistent()) { throw new CannotModifyPersistentRepresentationException("Representation " + globalId + " - " + schema + " - " + version + " is already persistent"); } String newVersion = generateNewVersionNumber(representationVersions, true); repVersion.setVersion(newVersion); repVersion.setPersistent(true); representationVersions.remove(repVersion); representationVersions.add(repVersion); return repVersion; } public List<Representation> listRepresentationVersions(String globalId, String schema) throws RepresentationNotExistsException { Map<String, List<Representation>> representations = records.get(globalId); if (representations == null) { throw new RepresentationNotExistsException(globalId); } List<Representation> representationVersions = representations.get(schema); if (representationVersions == null) { throw new RepresentationNotExistsException(); } List<Representation> result = new ArrayList<>(representationVersions.size()); for (Representation representation : representationVersions) { result.add(copy(representation)); } Collections.reverse(result); return result; } public Representation addOrReplaceFileInRepresentation(String globalId, String schema, String version, File file) throws RepresentationNotExistsException, CannotModifyPersistentRepresentationException { Map<String, List<Representation>> representations = records.get(globalId); if (representations == null) { throw new RepresentationNotExistsException(globalId); } List<Representation> representationVersions = representations.get(schema); if (representationVersions == null) { throw new RepresentationNotExistsException(); } Representation rep = getByVersion(representationVersions, version); if (rep == null) { throw new VersionNotExistsException(); } if (rep.isPersistent()) { throw new CannotModifyPersistentRepresentationException(); } ListIterator<File> filesIterator = rep.getFiles().listIterator(); while (filesIterator.hasNext()) { File f = filesIterator.next(); if (f.getFileName().equals(file.getFileName())) { filesIterator.remove(); break; } } rep.getFiles().add(file); return copy(rep); } public Representation removeFileFromRepresentation(String globalId, String schema, String version, String fileName) throws RepresentationNotExistsException, VersionNotExistsException, FileNotExistsException, CannotModifyPersistentRepresentationException { Map<String, List<Representation>> representations = records.get(globalId); if (representations == null) { throw new RepresentationNotExistsException(globalId); } List<Representation> representationVersions = representations.get(schema); if (representationVersions == null) { throw new RepresentationNotExistsException(); } Representation rep = getByVersion(representationVersions, version); if (rep == null) { throw new VersionNotExistsException(); } if (rep.isPersistent()) { throw new CannotModifyPersistentRepresentationException(); } for (File f : rep.getFiles()) { if (f.getFileName().equals(fileName)) { rep.getFiles().remove(f); return copy(rep); } } throw new FileNotExistsException(); } }