package se.cambio.cm.model.generic.dao; import se.cambio.cm.model.util.CMElement; import se.cambio.cm.model.util.CMTypeManager; import se.cambio.openehr.util.IOUtils; import se.cambio.openehr.util.Resources; import se.cambio.openehr.util.UnicodeBOMInputStream; import se.cambio.openehr.util.exceptions.InstanceNotFoundException; import se.cambio.openehr.util.exceptions.InternalErrorException; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.Date; public class ResourceGenericCMElementDAO <E extends CMElement> implements GenericCMElementDAO<E>{ private Class<E> cmElementClass; private Collection<String> fileExtensions; public ResourceGenericCMElementDAO(Class<E> cmElementClass){ this.cmElementClass = cmElementClass; } @Override public Collection<E> searchByIds(Collection<String> ids) throws InternalErrorException, InstanceNotFoundException { Collection<E> cmElements = new ArrayList<E>(); InputStream is = getInputStreamForResourceList(); if (is!=null) { Collection<String> resourceFileNamesIdsMap = getResourceFileNames(is); for (String resourceFileName : resourceFileNamesIdsMap) { try{ String fileExtension = matchingFileExtension(resourceFileName); String id = resourceFileName.substring(resourceFileName.lastIndexOf("/") + 1, resourceFileName.length() - fileExtension.length() - 1); if (ids.contains(id)) { E cmElement = getCMElement(resourceFileName); cmElements.add(cmElement); } }catch(Exception e){ throw new InternalErrorException(e); } } }else{ throw new InternalErrorException(new Exception("Resource list not found!")); } checkMissingInstance(ids, cmElements); return cmElements; } @Override public Collection<E> searchAll() throws InternalErrorException { Collection<E> cmElements = new ArrayList<E>(); InputStream is = getInputStreamForResourceList(); if (is!=null) { Collection<String> resourceFileNamesIdsMap = getResourceFileNames(is); for (String resourceFileName : resourceFileNamesIdsMap) { try{ E cmElement = getCMElement(resourceFileName); cmElements.add(cmElement); }catch(Exception e){ throw new InternalErrorException(e); } } }else{ throw new InternalErrorException(new Exception("Resource list not found!")); } return cmElements; } private E getCMElement(String resourceFileName) throws IOException, InternalErrorException { InputStream fis = ResourceGenericCMElementDAO.class.getClassLoader().getResourceAsStream(resourceFileName); UnicodeBOMInputStream ubis = new UnicodeBOMInputStream(fis); ubis.skipBOM(); String fileExtension = matchingFileExtension(resourceFileName); String id = resourceFileName.substring(resourceFileName.lastIndexOf("/") + 1, resourceFileName.length() - fileExtension.length() - 1); String source = IOUtils.toString(ubis, "UTF-8"); E cmElement = (E)new CMElementBuilder<E>() .setId(id) .setFormat(fileExtension) .setSource(source) .setLastUpdate(Calendar.getInstance().getTime()) .createCMElement(cmElementClass); return cmElement; } private InputStream getInputStreamForResourceList() throws InternalErrorException { return ResourceGenericCMElementDAO.class.getClassLoader().getResourceAsStream(Resources.RESOURCES_LIST); } private Collection<String> getResourceFileNames(InputStream is) throws InternalErrorException { Collection<String> resourceFileNames = new ArrayList<String>(); try { String resourceList = IOUtils.toString(is, "UTF-8"); for (String resourceFileName : resourceList.split("\n")) { resourceFileName = resourceFileName.trim(); String fileExtension = matchingFileExtension(resourceFileName); if (fileExtension != null) { //Remove the leading '\' resourceFileName = resourceFileName.replaceAll("\\\\", "/"); resourceFileNames.add(resourceFileName.substring(1, resourceFileName.length())); } } }catch (IOException e){ throw new InternalErrorException(e); } return resourceFileNames; } @Override public Collection<String> searchAllIds() throws InternalErrorException { Collection<String> ids = new ArrayList<String>(); InputStream is = getInputStreamForResourceList(); Collection<String> resourceFileNames = getResourceFileNames(is); for (String resourceFileName : resourceFileNames) { String fileExtension = matchingFileExtension(resourceFileName); String id = resourceFileName.substring(resourceFileName.lastIndexOf("/")+1,resourceFileName.length()-fileExtension.length()-1); ids.add(id); } return ids; } @Override public void insert(E cmElement) throws InternalErrorException { throw new UnsupportedOperationException("Not allowed on resources DAO"); } @Override public void update(E cmElement) throws InternalErrorException, InstanceNotFoundException { throw new UnsupportedOperationException("Not allowed on resources DAO"); } @Override public void remove(String id) throws InternalErrorException, InstanceNotFoundException { throw new UnsupportedOperationException("Not allowed on resources DAO"); } @Override public void removeAll() throws InternalErrorException { throw new UnsupportedOperationException("Not allowed on resources DAO"); } @Override public Date getLastUpdateDate() throws InternalErrorException { return Calendar.getInstance().getTime(); } private String matchingFileExtension(String fileName) throws InternalErrorException { for(String fileExtension: getFileExtensions()){ if (fileName.endsWith("."+fileExtension)){ return fileExtension; } } return null; } private void checkMissingInstance(Collection<String> ids, Collection<E> cmElements) throws InstanceNotFoundException { Collection<String> foundIds = new ArrayList<String>(); for (CMElement cmElement: cmElements){ foundIds.add(cmElement.getId()); } for(String id: ids){ if (!foundIds.contains(id)){ throw new InstanceNotFoundException(id, getCMElementClassName()); } } } private String getCMElementClassName() { return getCMElementClass().getSimpleName(); } private Class<E> getCMElementClass() { return cmElementClass; } public Collection<String> getFileExtensions() throws InternalErrorException { if (fileExtensions == null) { fileExtensions = CMTypeManager.getInstance().getCMTypeByClass(getCMElementClass()).getFileExtensions(); } return fileExtensions; } }