public LocatorDatasetReader read() throws IOException { selectedLocator = locatorWithFallbacks; DatasetWithFMI originalDatasetWithFMI = null; do { try { originalDatasetWithFMI = readFrom(selectedLocator); } catch (IOException e) { LOG.info( "Failed to read Data Set with iuid={} from {}@{}", selectedLocator.iuid, selectedLocator.getFilePath(), selectedLocator.getStorageSystem(), e); selectedLocator = selectedLocator.getFallbackLocator(); if (selectedLocator == null) throw e; LOG.info("Try read Data Set from alternative location"); } } while (originalDatasetWithFMI == null); Attributes dataset = originalDatasetWithFMI.getDataset(); if (context.getRemoteAE() != null) { storescuService.coerceFileBeforeMerge(selectedLocator, dataset, context); } dataset = Utils.mergeAndNormalize(dataset, (Attributes) selectedLocator.getObject()); if (context.getRemoteAE() != null) { storescuService.coerceAttributes(dataset, context); } datasetWithFMI = new DatasetWithFMI(originalDatasetWithFMI.getFileMetaInformation(), dataset); return this; }
@Override protected String selectTransferSyntaxFor(Association storeas, ArchiveInstanceLocator inst) throws UnsupportedStoreSCUException { Set<String> acceptedTransferSyntax = storeas.getTransferSyntaxesFor(inst.cuid); // check for SOP classes elimination if (context .getArchiveAEExtension() .getRetrieveSuppressionCriteria() .isCheckTransferCapabilities()) { inst = service.eliminateUnSupportedSOPClasses(inst, context); // check if eliminated then throw exception if (inst == null) throw new UnsupportedStoreSCUException("Unable to send instance, SOP class not configured"); if (isConfiguredAndAccepted(inst, storeas.getTransferSyntaxesFor(inst.cuid))) return inst.tsuid; else return getDefaultConfiguredTransferSyntax(inst); } if (acceptedTransferSyntax.contains(inst.tsuid)) return inst.tsuid; return storeas.getTransferSyntaxesFor(inst.cuid).contains(UID.ExplicitVRLittleEndian) ? UID.ExplicitVRLittleEndian : UID.ImplicitVRLittleEndian; }
@Override protected DataWriter createDataWriter(ArchiveInstanceLocator inst, String tsuid) throws IOException, UnsupportedStoreSCUException { if (inst == null || !(inst instanceof ArchiveInstanceLocator)) throw new UnsupportedStoreSCUException("Unable to send instance"); ArchiveAEExtension arcAEExt = context.getLocalAE().getAEExtension(ArchiveAEExtension.class); Attributes attrs = null; do { try { attrs = readFrom(inst); } catch (IOException e) { LOG.info( "Failed to read Data Set with iuid={} from {}@{}", inst.iuid, inst.getFilePath(), inst.getStorageSystem(), e); inst = inst.getFallbackLocator(); if (inst == null) { throw e; } LOG.info("Try to read Data Set from alternative location"); } } while (attrs == null); // check for suppression criteria if (context.getRemoteAE() != null) { String templateURI = arcAEExt .getRetrieveSuppressionCriteria() .getSuppressionCriteriaMap() .get(context.getRemoteAE().getAETitle()); if (templateURI != null) inst = service.applySuppressionCriteria(inst, attrs, templateURI, context); } service.coerceFileBeforeMerge(inst, attrs, context); // here we merge file attributes with attributes in the blob attrs = Utils.mergeAndNormalize(attrs, (Attributes) inst.getObject()); service.coerceAttributes(attrs, context); if (!tsuid.equals(inst.tsuid)) Decompressor.decompress(attrs, inst.tsuid); return new DataWriterAdapter(attrs); }
@Override public org.dcm4che3.net.service.BasicCStoreSCUResp cstore( final java.util.List<ArchiveInstanceLocator> instances, final Association storeas, final int priority) { ArrayList<ArchiveInstanceLocator> localyAvailable = (ArrayList<ArchiveInstanceLocator>) filterLocalOrExternalMatches(instances, true); ArrayList<ArchiveInstanceLocator> externallyAvailable = (ArrayList<ArchiveInstanceLocator>) filterLocalOrExternalMatches(instances, false); BasicCStoreSCUResp responseForLocalyAvailable = null; if (!localyAvailable.isEmpty()) responseForLocalyAvailable = super.cstore(localyAvailable, storeas, priority); // initialize remaining response BasicCStoreSCUResp finalResponse = extendResponse(responseForLocalyAvailable); if (!externallyAvailable.isEmpty()) { FetchForwardCallBack moveCallBack = new FetchForwardCallBack() { @Override public void onFetch( Collection<ArchiveInstanceLocator> instances, BasicCStoreSCUResp resp) { pushInstances((ArrayList<ArchiveInstanceLocator>) instances, storeas, priority); } }; FetchForwardCallBack wadoCallBack = new FetchForwardCallBack() { @Override public void onFetch( Collection<ArchiveInstanceLocator> instances, BasicCStoreSCUResp resp) { pushInstances((ArrayList<ArchiveInstanceLocator>) instances, storeas, priority); } }; finalResponse = service .getFetchForwardService() .fetchForward( instances.size(), finalResponse, externallyAvailable, storeas, priority, wadoCallBack, moveCallBack); if (failed.size() > 0) { if (failed.size() == nr_instances) status = Status.UnableToPerformSubOperations; else status = Status.OneOrMoreFailures; } else { status = Status.Success; } setChanged(); notifyObservers(); } return finalResponse; }
private Attributes readFrom(ArchiveInstanceLocator inst) throws IOException { try (DicomInputStream din = new DicomInputStream(service.getFile(inst).toFile())) { IncludeBulkData includeBulkData = IncludeBulkData.URI; int stopTag = -1; if (withoutBulkData) { if (((ArchiveInstanceLocator) inst).isWithoutBulkdata()) { includeBulkData = IncludeBulkData.YES; } else { includeBulkData = IncludeBulkData.NO; stopTag = Tag.PixelData; } } din.setIncludeBulkData(includeBulkData); return din.readDataset(-1, stopTag); } }
private DatasetWithFMI readFrom(ArchiveInstanceLocator inst) throws IOException { try (DicomInputStream din = new DicomInputStream(storescuService.getFile(inst).toFile())) { din.setIncludeBulkData(IncludeBulkData.URI); return din.readDatasetWithFMI(); } }