/* * 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.detector.model.pipeline.preprocessors; 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.InferenceMode; import de.fub.maps.project.detector.model.process.AbstractDetectorProcess; import de.fub.maps.project.detector.model.process.DetectorProcess; import de.fub.maps.project.detector.model.xmls.ProcessDescriptor; import de.fub.utilsmodule.icons.IconRegister; import de.fub.utilsmodule.node.CustomAbstractnode; import de.fub.utilsmodule.node.property.ProcessProperty; import de.fub.utilsmodule.synchronizer.ModelSynchronizer; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.image.BufferedImage; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.text.MessageFormat; import java.util.Collection; import java.util.List; import javax.swing.JComponent; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import org.openide.nodes.Children; import org.openide.nodes.Node; import org.openide.nodes.Sheet; import org.openide.util.Cancellable; import org.openide.util.Lookup; import org.openide.util.NbBundle; import org.openide.util.WeakListeners; import org.openide.util.lookup.Lookups; /** * * @author Serdar */ public abstract class FilterProcess extends AbstractDetectorProcess<List<TrackSegment>, List<TrackSegment>> implements Cancellable { protected static String PROP_NAME_FILTER_SCOPE = "filterprocess.scope"; private static Image defaultImage; protected InferenceMode scope = InferenceMode.ALL_MODE; public FilterProcess() { } @Override protected Node createNodeDelegate() { return new FilterProcessNode(this); } public InferenceMode getScope() { return scope; } @Override public JComponent getSettingsView() { return null; } public FilterScope getFilterScope() { return FilterScope.TRAINING_AND_INFERENCE; } @Override protected Image getDefaultImage() { return createDefaultImage(); } private static synchronized Image createDefaultImage() { defaultImage = IconRegister.findRegisteredIcon("filterIcon16.png"); if (defaultImage == null) { defaultImage = new BufferedImage(16, 16, BufferedImage.TYPE_4BYTE_ABGR); Graphics graphics = defaultImage.getGraphics(); if (graphics instanceof Graphics2D) { Graphics2D g2D = (Graphics2D) graphics; g2D.setPaint(new Color(255, 255, 255, 0)); g2D.fillRect(0, 0, 16, 16); g2D.dispose(); } } return defaultImage; } @Override public boolean cancel() { return false; } /** * This is a factory method to find and create all via * <code>@ServiceProvider</code> registered FilterProcesses. * * @return A list of FilterProcess instances. */ public static synchronized Collection<FilterProcess> findAll() { return findAll(FilterProcess.class); } /** * * @param descriptor * @param detector * @return * @throws * de.fub.maps.project.detector.model.process.DetectorProcess.DetectorProcessNotFoundException */ public static synchronized FilterProcess find(ProcessDescriptor descriptor, Detector detector) throws DetectorProcessNotFoundException { assert descriptor != null; FilterProcess filterProcess = find(descriptor.getJavaType(), detector); if (filterProcess != null) { filterProcess.setProcessDescriptor(descriptor); } return filterProcess; } /** * * @param qualifiedInstanceName * @param detector * @return * @throws * de.fub.maps.project.detector.model.process.DetectorProcess.DetectorProcessNotFoundException */ public static synchronized FilterProcess find(String qualifiedInstanceName, Detector detector) throws DetectorProcessNotFoundException { FilterProcess filterProcess = null; try { Class<?> clazz = null; ClassLoader classLoader = Lookup.getDefault().lookup(ClassLoader.class); // prefer netbeans classloader if (classLoader != null) { clazz = classLoader.loadClass(qualifiedInstanceName); } else { // fall back clazz = Class.forName(qualifiedInstanceName); } if (FilterProcess.class.isAssignableFrom(clazz)) { @SuppressWarnings("unchecked") Class<FilterProcess> filterProcessClass = (Class<FilterProcess>) clazz; filterProcess = DetectorProcess.find(filterProcessClass, detector); } else { throw new DetectorProcessNotFoundException(MessageFormat.format("{0} is not type of {1}", clazz.getSimpleName(), FilterProcess.class.getSimpleName())); } } catch (Throwable ex) { throw new DetectorProcessNotFoundException(ex); } return filterProcess; } /** * Default visual representer implementation of Filterprocess instances. */ @NbBundle.Messages({"CLT_Filter_Parameter=Parameters"}) private static class FilterProcessNode extends CustomAbstractnode implements PropertyChangeListener, ChangeListener { private final FilterProcess filterProcess; private Sheet.Set set; private ModelSynchronizer.ModelSynchronizerClient modelSynchronizerClient; public FilterProcessNode(FilterProcess filterProcess) { super(Children.LEAF, Lookups.fixed(filterProcess)); this.filterProcess = filterProcess; this.filterProcess.addPropertyChangeListener(WeakListeners.propertyChange(FilterProcessNode.this, this.filterProcess)); setDisplayName(filterProcess.getName()); setShortDescription(filterProcess.getDescription()); } @Override protected Sheet createSheet() { Sheet sheet = Sheet.createDefault(); if (filterProcess.getDetector() != null) { modelSynchronizerClient = filterProcess.getDetector().create(FilterProcessNode.this); set = Sheet.createPropertiesSet(); set.setDisplayName(Bundle.CLT_Filter_Parameter()); sheet.put(set); reinitSet(); } return sheet; } private void reinitSet() { List<de.fub.maps.project.detector.model.xmls.Property> propertyList = filterProcess.getProcessDescriptor().getProperties().getPropertyList(); ProcessProperty property = null; for (de.fub.maps.project.detector.model.xmls.Property xmlProperty : propertyList) { property = new ProcessProperty(modelSynchronizerClient, xmlProperty); set.put(property); } } @Override public Image getIcon(int type) { Image image = null; switch (this.filterProcess.getProcessState()) { case ERROR: image = IconRegister.findRegisteredIcon("processIconError.png"); break; case INACTIVE: image = IconRegister.findRegisteredIcon("processIconNormal.png"); break; case RUNNING: image = IconRegister.findRegisteredIcon("processIconRun.png"); break; default: throw new AssertionError(); } return image != null ? image : super.getIcon(type); } @Override public Image getOpenedIcon(int type) { return getIcon(type); } @Override public void propertyChange(PropertyChangeEvent evt) { if (FilterProcess.PROP_NAME_PROCESS_STATE.equals(evt.getPropertyName())) { fireIconChange(); } } @Override public void stateChanged(ChangeEvent e) { if (modelSynchronizerClient != null) { reinitSet(); } } } public enum FilterScope { // Training = CrossValidation + Trainings TRAINING, // only inference INFERENCE, // training and inference TRAINING_AND_INFERENCE; } }