/* * Copyright (C) 2013 Serdar * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package de.fub.maps.project.plugins.tasks.map; import de.fub.gpxmodule.xml.Gpx; import de.fub.maps.project.aggregator.pipeline.AggregatorProcessPipeline; import de.fub.maps.project.aggregator.xml.Source; import de.fub.maps.project.api.process.ProcessState; import de.fub.maps.project.detector.model.Detector; import de.fub.maps.project.detector.model.gpx.TrackSegment; import de.fub.maps.project.detector.model.inference.InferenceModelResultDataSet; import de.fub.maps.project.detector.model.pipeline.postprocessors.tasks.Task; import de.fub.maps.project.detector.model.xmls.ProcessDescriptor; import de.fub.maps.project.detector.model.xmls.Property; import de.fub.maps.project.detector.utils.GPSUtils; import de.fub.maps.project.models.Aggregator; import de.fub.maps.project.utils.AggregatorUtils; import de.fub.utilsmodule.Collections.ObservableArrayList; import de.fub.utilsmodule.Collections.ObservableList; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.net.URLEncoder; import java.text.MessageFormat; import java.util.HashSet; import java.util.List; import java.util.Map.Entry; import javax.swing.JComponent; import javax.xml.bind.JAXBException; import org.openide.filesystems.FileObject; import org.openide.nodes.Children; import org.openide.nodes.Node; import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.util.lookup.ServiceProvider; /** * Implementation of an Detector task, which handels the creation of an * specified Aggregator for each transport mode defined in the result of the * classification of the inferenceModel of the Detector. * * Each Aggregator creates a navigation graph. * * @author Serdar */ @NbBundle.Messages({ "CLT_MapRenderer_Name=Map Renderer", "CLT_MapRenderer_Description=Renders Gps data with the help of an Aggregator", "CLT_MapRenderer_Property_AggregationFilePath_Name=Aggregator File Path", "CLT_MapRenderer_Property_AggregationFilePath_Description=The file path to the aggregator file.", "CLT_MapRenderer_Property_OpenAfterFinished_Name=Open after inference is finished", "CLT_MapRenderer_Property_OpenAfterFinished_Description=Opens after aggregation is finished all aggregator panels." }) @ServiceProvider(service = Task.class) public class MapRenderer extends Task { static final String PROP_NAME_AGGREGATOR_FILE_PATH = "maprenderer.aggregator.file.path"; private static final String PROP_NAME_OPEN_AFTER_FINISHED = "maprenderer.open.after.finished"; private final ObservableList<Aggregator> aggregatorList = new ObservableArrayList<Aggregator>(); private final MapRendererSupport mapRendererSupport = new MapRendererSupport(MapRenderer.this); public MapRenderer() { validate(); } @Override protected void setDetector(Detector detector) { super.setDetector(detector); } @Override protected void setProcessDescriptor(ProcessDescriptor processDescriptor) { super.setProcessDescriptor(processDescriptor); validate(); } public ObservableList<Aggregator> getAggregatorList() { return aggregatorList; } /** * Checks whether a valid aggregator template is provider for this * MapRenderer instance. */ private void validate() { setProcessState(ProcessState.INACTIVE); try { Aggregator aggregatorTemplate = mapRendererSupport.createAggregator(); if (aggregatorTemplate == null) { throw new FileNotFoundException(); } else { aggregatorTemplate.getDataObject().getPrimaryFile().delete(); } } catch (FileNotFoundException ex) { setProcessState(ProcessState.SETTING_ERROR); } catch (IOException ex) { Exceptions.printStackTrace(ex); } } /** * deletes all created Aggregator instances with there descriptor files. */ public void clear() { if (!aggregatorList.isEmpty()) { for (Aggregator aggregator : aggregatorList) { try { aggregator.getDataObject().getPrimaryFile().delete(); } catch (IOException ex) { Exceptions.printStackTrace(ex); } } aggregatorList.clear(); } // this is hack and should have a better work around. fireProcessFinishedEvent(); } @Override protected void start() { clear(); try { Aggregator aggregator = mapRendererSupport.createAggregator(); if (aggregator != null && aggregator.getAggregatorDescriptor() != null) { InferenceModelResultDataSet resultDataSet = getResultDataSet(); for (Entry<String, HashSet<TrackSegment>> entry : resultDataSet.entrySet()) { try { if (entry.getValue() != null && !entry.getValue().isEmpty()) { // specify the name of the aggregator aggregator.getAggregatorDescriptor().setName( MessageFormat.format("{0} [{1}]", entry.getKey(), getDetector().getDetectorDescriptor().getName())); // to be sure there is no datasource in the template // we clear the source list of the aggregator List<Source> sourceList = aggregator.getSourceList(); sourceList.clear(); FileObject tmpFolder = mapRendererSupport.createTempFolder( URLEncoder.encode( MessageFormat.format("MapRendererTransportation: {0}", aggregator.getAggregatorDescriptor().getName()), "UTF-8")); Gpx gpx = GPSUtils.convert(entry.getValue()); File tmpFile = mapRendererSupport.createTmpfile(tmpFolder); try { AggregatorUtils.saveGpxToFile(tmpFile, gpx); sourceList.add(new Source(tmpFile.getAbsolutePath())); } catch (JAXBException ex) { Exceptions.printStackTrace(ex); } aggregator.updateSource(); aggregator.start(); aggregatorList.add(aggregator); } } catch (IOException ex) { Exceptions.printStackTrace(ex); } finally { aggregator = mapRendererSupport.createAggregator(); } } // TODO: display aggregators if open.after.finished property // is true } else { setProcessState(ProcessState.SETTING_ERROR); } } catch (FileNotFoundException ex) { throw new AggregatorProcessPipeline.PipelineException(ex.getMessage(), ex); } } public Detector getProcessParentDetector() { return getDetector(); } @Override public JComponent getSettingsView() { return null; } @Override public String getName() { if (getProcessDescriptor() != null && getProcessDescriptor().getName() != null) { return getProcessDescriptor().getName(); } return Bundle.CLT_MapRenderer_Name(); } @Override public String getDescription() { if (getProcessDescriptor() != null && getProcessDescriptor().getDescription() != null) { return getProcessDescriptor().getDescription(); } return Bundle.CLT_MapRenderer_Description(); } @Override protected Node createNodeDelegate() { return new MapRendererNode(MapRenderer.this); } @Override protected ProcessDescriptor createProcessDescriptor() { ProcessDescriptor descriptor = new ProcessDescriptor(); descriptor.setJavaType(MapRenderer.class.getName()); descriptor.setName(Bundle.CLT_MapRenderer_Name()); descriptor.setDescription(Bundle.CLT_MapRenderer_Description()); Property property = new Property(); property.setId(PROP_NAME_AGGREGATOR_FILE_PATH); property.setJavaType(String.class.getName()); property.setName(Bundle.CLT_MapRenderer_Property_AggregationFilePath_Name()); property.setDescription(Bundle.CLT_MapRenderer_Property_AggregationFilePath_Description()); descriptor.getProperties().getPropertyList().add(property); property = new Property(); property.setId(PROP_NAME_OPEN_AFTER_FINISHED); property.setJavaType(Boolean.class.getName()); property.setValue(Boolean.TRUE.toString()); property.setName(Bundle.CLT_MapRenderer_Property_OpenAfterFinished_Name()); property.setDescription(Bundle.CLT_MapRenderer_Property_OpenAfterFinished_Description()); descriptor.getProperties().getPropertyList().add(property); return descriptor; } /** * The propose of this class is only for access reasons. The protector * access to the TaskProcessNode will be extended to package access. */ static abstract class MapRendererProcessNode extends Task.TaskProcessNode { public MapRendererProcessNode(Task taskProcess) { super(taskProcess); } public MapRendererProcessNode(Children children, Task taskProcess) { super(children, taskProcess); } } }