/******************************************************************************* * Copyright (c) 2016 Weasis Team and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nicolas Roduit - initial API and implementation *******************************************************************************/ package org.weasis.core.ui.editor; import java.awt.Rectangle; import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.weasis.core.api.explorer.ObservableEvent; import org.weasis.core.api.explorer.model.AbstractFileModel; import org.weasis.core.api.explorer.model.DataExplorerModel; import org.weasis.core.api.gui.util.AppProperties; import org.weasis.core.api.media.MimeInspector; import org.weasis.core.api.media.data.Codec; import org.weasis.core.api.media.data.ImageElement; import org.weasis.core.api.media.data.MediaElement; import org.weasis.core.api.media.data.MediaReader; import org.weasis.core.api.media.data.MediaSeries; import org.weasis.core.api.media.data.MediaSeriesGroup; import org.weasis.core.api.media.data.MediaSeriesGroupNode; import org.weasis.core.api.media.data.Series; import org.weasis.core.api.media.data.TagW; import org.weasis.core.api.service.BundleTools; import org.weasis.core.ui.docking.UIManager; import org.weasis.core.ui.model.GraphicModel; import org.weasis.core.ui.serialize.XmlSerializer; public class ViewerPluginBuilder { private static final Logger LOGGER = LoggerFactory.getLogger(ViewerPluginBuilder.class); public static final String CMP_ENTRY_BUILD_NEW_VIEWER = "cmp.entry.viewer"; //$NON-NLS-1$ public static final String BEST_DEF_LAYOUT = "best.def.layout"; //$NON-NLS-1$ public static final String OPEN_IN_SELECTION = "add.in.selected.view"; // For only one image //$NON-NLS-1$ public static final String ADD_IN_SELECTED_VIEW = "add.in.selected.view"; // For non DICOM images //$NON-NLS-1$ public static final String SCREEN_BOUND = "screen.bound"; //$NON-NLS-1$ public static final String ICON = "plugin.icon"; //$NON-NLS-1$ public static final String UID = "plugin.uid"; //$NON-NLS-1$ public static final FileModel DefaultDataModel = new FileModel(); private final SeriesViewerFactory factory; private final List<? extends MediaSeries<? extends MediaElement>> series; private final DataExplorerModel model; private final Map<String, Object> properties; public ViewerPluginBuilder(SeriesViewerFactory factory, List<? extends MediaSeries<? extends MediaElement>> series, DataExplorerModel model, Map<String, Object> props) { if (factory == null || series == null || model == null) { throw new IllegalArgumentException(); } this.factory = factory; this.series = series; this.model = model; this.properties = props == null ? Collections.synchronizedMap(new HashMap<String, Object>()) : props; } public SeriesViewerFactory getFactory() { return factory; } public List<MediaSeries<MediaElement>> getSeries() { return (List<MediaSeries<MediaElement>>) series; } public DataExplorerModel getModel() { return model; } public Map<String, Object> getProperties() { return properties; } public static void openSequenceInPlugin(SeriesViewerFactory factory, MediaSeries<? extends MediaElement> series, DataExplorerModel model, boolean compareEntryToBuildNewViewer, boolean removeOldSeries) { if (factory == null || series == null || model == null) { return; } ArrayList<MediaSeries<? extends MediaElement>> list = new ArrayList<>(1); list.add(series); openSequenceInPlugin(factory, list, model, compareEntryToBuildNewViewer, removeOldSeries); } public static void openSequenceInPlugin(SeriesViewerFactory factory, List<? extends MediaSeries<? extends MediaElement>> series, DataExplorerModel model, boolean compareEntryToBuildNewViewer, boolean removeOldSeries) { openSequenceInPlugin(factory, series, model, compareEntryToBuildNewViewer, removeOldSeries, null); } public static void openSequenceInPlugin(SeriesViewerFactory factory, List<? extends MediaSeries<? extends MediaElement>> series, DataExplorerModel model, boolean compareEntryToBuildNewViewer, boolean removeOldSeries, Rectangle screenBound) { if (factory == null || series == null || model == null) { return; } Map<String, Object> props = Collections.synchronizedMap(new HashMap<String, Object>()); props.put(CMP_ENTRY_BUILD_NEW_VIEWER, compareEntryToBuildNewViewer); props.put(BEST_DEF_LAYOUT, removeOldSeries); props.put(SCREEN_BOUND, screenBound); ViewerPluginBuilder builder = new ViewerPluginBuilder(factory, series, model, props); model.firePropertyChange(new ObservableEvent(ObservableEvent.BasicAction.REGISTER, model, null, builder)); } public static void openSequenceInPlugin(ViewerPluginBuilder builder) { if (builder == null) { return; } DataExplorerModel model = builder.getModel(); model.firePropertyChange(new ObservableEvent(ObservableEvent.BasicAction.REGISTER, model, null, builder)); } public static void openSequenceInDefaultPlugin(List<? extends MediaSeries<? extends MediaElement>> series, DataExplorerModel model, boolean compareEntryToBuildNewViewer, boolean removeOldSeries) { ArrayList<String> mimes = new ArrayList<>(); for (MediaSeries<?> s : series) { String mime = s.getMimeType(); if (mime != null && !mimes.contains(mime)) { mimes.add(mime); } } for (String mime : mimes) { SeriesViewerFactory plugin = UIManager.getViewerFactory(mime); if (plugin != null) { ArrayList<MediaSeries<? extends MediaElement>> seriesList = new ArrayList<>(); for (MediaSeries<? extends MediaElement> s : series) { if (mime.equals(s.getMimeType())) { seriesList.add(s); } } openSequenceInPlugin(plugin, seriesList, model, compareEntryToBuildNewViewer, removeOldSeries); } } } public static void openSequenceInDefaultPlugin(MediaSeries<MediaElement> series, DataExplorerModel model, boolean compareEntryToBuildNewViewer, boolean removeOldSeries) { if (series != null) { String mime = series.getMimeType(); SeriesViewerFactory plugin = UIManager.getViewerFactory(mime); if (plugin == null) { plugin = DefaultMimeAppFactory.getInstance(); } openSequenceInPlugin(plugin, series, model == null ? DefaultDataModel : model, compareEntryToBuildNewViewer, removeOldSeries); } } public static void openSequenceInDefaultPlugin(MediaElement media, DataExplorerModel model, boolean compareEntryToBuildNewViewer, boolean bestDefaultLayout) { if (media != null) { openSequenceInDefaultPlugin(media.getMediaReader().getMediaSeries(), model, compareEntryToBuildNewViewer, bestDefaultLayout); } } public static void openSequenceInDefaultPlugin(File file, boolean compareEntryToBuildNewViewer, boolean bestDefaultLayout) { MediaReader reader = getMedia(file); if (reader != null) { MediaSeries<MediaElement> s = buildMediaSeriesWithDefaultModel(reader); openSequenceInDefaultPlugin(s, DefaultDataModel, compareEntryToBuildNewViewer, bestDefaultLayout); } } public static MediaReader getMedia(File file) { return getMedia(file, true); } public static MediaReader getMedia(File file, boolean systemReader) { if (file != null && file.canRead()) { // If file has been downloaded or copied boolean cache = file.getPath().startsWith(AppProperties.FILE_CACHE_DIR.getPath()); String mimeType = MimeInspector.getMimeType(file); if (mimeType != null) { Codec codec = BundleTools.getCodec(mimeType, "dcm4che"); //$NON-NLS-1$ if (codec != null) { MediaReader mreader = codec.getMediaIO(file.toURI(), mimeType, null); if (cache) { mreader.getFileCache().setOriginalTempFile(file); } return mreader; } } if (systemReader) { MediaReader mreader = new DefaultMimeIO(file.toURI(), null); if (cache) { mreader.getFileCache().setOriginalTempFile(file); } return mreader; } } return null; } public static MediaSeries<MediaElement> buildMediaSeriesWithDefaultModel(MediaReader reader) { return buildMediaSeriesWithDefaultModel(reader, null, null, null); } public static MediaSeries<MediaElement> buildMediaSeriesWithDefaultModel(MediaReader reader, String groupUID, TagW groupName, String groupValue) { return buildMediaSeriesWithDefaultModel(reader, groupUID, groupName, groupValue, null); } public static MediaSeries<MediaElement> buildMediaSeriesWithDefaultModel(MediaReader reader, String groupUID, TagW groupName, String groupValue, String seriesUID) { if (reader instanceof DefaultMimeIO) { return reader.getMediaSeries(); } MediaSeries<MediaElement> series = null; // Require to read the header MediaElement[] medias = reader.getMediaElement(); if (medias == null) { return null; } String sUID = seriesUID == null ? UUID.randomUUID().toString() : seriesUID; String gUID = groupUID == null ? UUID.randomUUID().toString() : groupUID; MediaSeriesGroup group1 = DefaultDataModel.getHierarchyNode(MediaSeriesGroupNode.rootNode, gUID); if (group1 == null) { group1 = new MediaSeriesGroupNode(TagW.Group, gUID, AbstractFileModel.group.getTagView()); group1.setTagNoNull(groupName, groupValue); DefaultDataModel.addHierarchyNode(MediaSeriesGroupNode.rootNode, group1); } MediaSeriesGroup group2 = DefaultDataModel.getHierarchyNode(group1, sUID); if (group2 instanceof Series) { series = (Series<MediaElement>) group2; } try { if (series == null) { series = reader.getMediaSeries(); series.setTag(TagW.ExplorerModel, DefaultDataModel); DefaultDataModel.addHierarchyNode(group1, series); } else { // Test if SOPInstanceUID already exists TagW sopTag = TagW.get("SOPInstanceUID"); //$NON-NLS-1$ if (series instanceof Series && ((Series<?>) series).hasMediaContains(sopTag, reader.getTagValue(sopTag))) { return series; } for (MediaElement media : medias) { series.addMedia(media); } } for (MediaElement media : medias) { if (media instanceof ImageElement) { File gpxFile = new File(media.getFile().getPath() + ".xml"); //$NON-NLS-1$ GraphicModel graphicModel = XmlSerializer.readPresentationModel(gpxFile); if (graphicModel != null) { media.setTag(TagW.PresentationModel, graphicModel); } } } } catch (Exception e) { LOGGER.error("Build series error", e); //$NON-NLS-1$ } finally { reader.reset(); } return series; } }