org.openbase.bco.manager.scene.visual.SceneCreationPanel.java Source code

Java tutorial

Introduction

Here is the source code for org.openbase.bco.manager.scene.visual.SceneCreationPanel.java

Source

package org.openbase.bco.manager.scene.visual;

/*
 * #%L
 * BCO Manager Scene Visualisation
 * %%
 * Copyright (C) 2015 - 2018 openbase.org
 * %%
 * 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/gpl-3.0.html>.
 * #L%
 */
import java.awt.Color;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.ExecutionException;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JOptionPane;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.openbase.bco.dal.remote.unit.scene.SceneRemote;
import org.openbase.bco.dal.visual.util.SelectorPanel.LocationUnitConfigHolder;
import org.openbase.bco.dal.visual.util.StatusPanel;
import org.openbase.bco.registry.remote.Registries;
import org.openbase.jul.exception.CouldNotPerformException;
import org.openbase.jul.exception.InitializationException;
import org.openbase.jul.exception.NotAvailableException;
import org.openbase.jul.exception.VerificationFailedException;
import org.openbase.jul.exception.printer.ExceptionPrinter;
import org.openbase.jul.exception.printer.LogLevel;
import org.openbase.jul.extension.rst.processing.LabelProcessor;
import org.openbase.jul.pattern.Observable;
import org.openbase.jul.pattern.ObservableImpl;
import org.openbase.jul.pattern.Observer;
import org.slf4j.LoggerFactory;
import rst.configuration.LabelType.Label;
import rst.domotic.registry.UnitRegistryDataType.UnitRegistryData;
import rst.domotic.service.ServiceStateDescriptionType.ServiceStateDescription;
import rst.domotic.state.ActivationStateType.ActivationState;
import rst.domotic.state.EnablingStateType;
import rst.domotic.unit.UnitConfigType.UnitConfig;
import rst.domotic.unit.UnitTemplateType;
import rst.domotic.unit.UnitTemplateType.UnitTemplate.UnitType;
import rst.domotic.unit.scene.SceneConfigType.SceneConfig;

public class SceneCreationPanel extends javax.swing.JPanel {

    protected static final org.slf4j.Logger logger = LoggerFactory.getLogger(SceneCreationPanel.class);

    private final ObservableImpl<SceneConfig> observable;
    private UnitConfig lastSelected = null;
    private LocationUnitConfigHolder location = null;

    /**
     * Creates new form SceneCreationPanel
     *
     */
    public SceneCreationPanel() {
        initComponents();
        observable = new ObservableImpl<>();
    }

    public void init() throws CouldNotPerformException, InterruptedException {
        StatusPanel.getInstance().setStatus("Wait for scene registry data...", StatusPanel.StatusType.INFO,
                Registries.getUnitRegistry().getDataFuture());
        Registries.getUnitRegistry(true);
        StatusPanel.getInstance().setStatus("Scene registry loaded.", StatusPanel.StatusType.INFO, 3);
        initDynamicComponents();
        updateDynamicComponents();
    }

    private void initDynamicComponents()
            throws CouldNotPerformException, InitializationException, InterruptedException {
        Registries.getUnitRegistry()
                .addDataObserver((final Observable<UnitRegistryData> source, UnitRegistryData data) -> {
                    updateDynamicComponents();
                });
        locationSelectorPanel
                .addObserver((final Observable<LocationUnitConfigHolder> source, LocationUnitConfigHolder data) -> {
                    location = data;
                    logger.info("location update:" + location);
                });
        // init locationSelectorPanel after registering the observer so that the selected location is recieved from the start
        locationSelectorPanel.init(false);
    }

    private void updateDynamicComponents() throws CouldNotPerformException {

        if (!Registries.getUnitRegistry().isDataAvailable()) {
            return;
        }

        ArrayList<SceneUnitConfigHolder> sceneConfigHolderList = new ArrayList<>();
        for (final UnitConfig sceneUnitConfig : Registries.getUnitRegistry().getUnitConfigs(UnitType.SCENE)) {
            sceneConfigHolderList.add(new SceneUnitConfigHolder(sceneUnitConfig));
        }

        if (sceneConfigHolderList.isEmpty()) {
            sceneSelectionComboBox.setEnabled(false);
            return;
        } else {
            sceneSelectionComboBox.setEnabled(true);
        }

        Collections.sort(sceneConfigHolderList);
        sceneSelectionComboBox.setModel(new DefaultComboBoxModel(sceneConfigHolderList.toArray()));
        if (lastSelected == null) {
            sceneSelectionComboBox.setSelectedIndex(0);
            lastSelected = ((SceneUnitConfigHolder) sceneSelectionComboBox.getSelectedItem()).getConfig();
            observable.notifyObservers(lastSelected.getSceneConfig());
        } else {
            sceneSelectionComboBox.setSelectedItem(new SceneUnitConfigHolder(lastSelected));
        }
    }

    public void updateSceneConfig(List<ServiceStateDescription> servicestateDescription)
            throws CouldNotPerformException {
        UnitConfig.Builder sceneUnitConfig = ((SceneUnitConfigHolder) sceneSelectionComboBox.getSelectedItem())
                .getConfig().toBuilder();
        sceneUnitConfig.getSceneConfigBuilder().clearRequiredServiceStateDescription();
        sceneUnitConfig.getSceneConfigBuilder().clearOptionalServiceStateDescription();
        sceneUnitConfig.getSceneConfigBuilder().addAllRequiredServiceStateDescription(servicestateDescription);
        sceneUnitConfig.getPlacementConfigBuilder().setLocationId(location.getConfig().getId());
        logger.info("save location:" + location.getConfig().getLabel());
        try {
            if (!Registries.getUnitRegistry().containsUnitConfig(sceneUnitConfig.build())) {
                logger.debug("Registering scene from updateSceneConfig");
                lastSelected = Registries.getUnitRegistry().registerUnitConfig(sceneUnitConfig.build()).get();
            } else {
                lastSelected = Registries.getUnitRegistry().updateUnitConfig(sceneUnitConfig.build()).get();
            }
        } catch (ExecutionException | InterruptedException ex) {
            throw new CouldNotPerformException("Could not register/update scene", ex);
        }
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        sceneSelectionComboBox = new javax.swing.JComboBox();
        newButton = new javax.swing.JButton();
        deleteButton = new javax.swing.JButton();
        locationSelectorPanel = new org.openbase.bco.manager.scene.visual.LocationSelectorPanel();
        applyUpdateButton = new javax.swing.JButton();

        sceneSelectionComboBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                sceneSelectionComboBoxActionPerformed(evt);
            }
        });

        newButton.setText("New");
        newButton.setMaximumSize(new java.awt.Dimension(81, 25));
        newButton.setMinimumSize(new java.awt.Dimension(81, 25));
        newButton.setPreferredSize(new java.awt.Dimension(81, 25));
        newButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                newButtonActionPerformed(evt);
            }
        });

        deleteButton.setText("Delete");
        deleteButton.setMaximumSize(new java.awt.Dimension(80, 25));
        deleteButton.setMinimumSize(new java.awt.Dimension(80, 25));
        deleteButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                deleteButtonActionPerformed(evt);
            }
        });

        applyUpdateButton.setText("Apply Scene");
        applyUpdateButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                applyUpdateButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(
                javax.swing.GroupLayout.Alignment.TRAILING,
                layout.createSequentialGroup().addContainerGap()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                .addComponent(locationSelectorPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 0,
                                        Short.MAX_VALUE)
                                .addComponent(sceneSelectionComboBox, 0, 394, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                .addGroup(layout.createSequentialGroup()
                                        .addComponent(newButton, javax.swing.GroupLayout.PREFERRED_SIZE, 73,
                                                javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                        .addComponent(deleteButton, javax.swing.GroupLayout.PREFERRED_SIZE,
                                                javax.swing.GroupLayout.DEFAULT_SIZE,
                                                javax.swing.GroupLayout.PREFERRED_SIZE))
                                .addComponent(applyUpdateButton, javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addContainerGap()));
        layout.setVerticalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup().addContainerGap().addGroup(layout
                        .createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(sceneSelectionComboBox, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(newButton, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(deleteButton, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(18, 18, 18)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(locationSelectorPanel, javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(applyUpdateButton, javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addContainerGap()));
    }// </editor-fold>//GEN-END:initComponents

    private void sceneSelectionComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sceneSelectionComboBoxActionPerformed
        //return if no new scene has been selected
        if (sceneSelectionComboBox.getSelectedIndex() == -1 || (lastSelected != null && lastSelected.getId()
                .equals(((SceneUnitConfigHolder) sceneSelectionComboBox.getSelectedItem()).getConfig().getId()))) {
            return;
        }

        lastSelected = ((SceneUnitConfigHolder) sceneSelectionComboBox.getSelectedItem()).getConfig();
        locationSelectorPanel.updateSelection(lastSelected.getPlacementConfig().getLocationId());
        try {
            observable.notifyObservers(lastSelected.getSceneConfig());
        } catch (CouldNotPerformException ex) {
            ExceptionPrinter.printHistory(new CouldNotPerformException("Could not notify observers!", ex), logger,
                    LogLevel.WARN);
        }
    }//GEN-LAST:event_sceneSelectionComboBoxActionPerformed

    private void newButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newButtonActionPerformed
        if (location == null) {
            logger.error("You have to select a location first!");
            return;
        }
        String label = JOptionPane.showInputDialog(this, "Enter scene label");
        //is null if cancel has been pressed
        if (label == null) {
            return;
        }
        try {
            logger.info("Registering scene from new button");
            UnitConfig.Builder unitConfig = UnitConfig.newBuilder()
                    .setLabel(LabelProcessor.addLabel(Label.newBuilder(), Locale.ENGLISH, label));
            unitConfig.setUnitType(UnitTemplateType.UnitTemplate.UnitType.SCENE);
            unitConfig.getPlacementConfigBuilder().setLocationId(location.getConfig().getId());
            unitConfig.setEnablingState(EnablingStateType.EnablingState.newBuilder()
                    .setValue(EnablingStateType.EnablingState.State.ENABLED));
            unitConfig.setSceneConfig(SceneConfig.getDefaultInstance());
            lastSelected = Registries.getUnitRegistry().registerUnitConfig(unitConfig.build()).get();
            updateDynamicComponents();
            observable.notifyObservers(lastSelected.getSceneConfig());
        } catch (CouldNotPerformException | InterruptedException | ExecutionException ex) {
            ExceptionPrinter.printHistory(ex, logger, LogLevel.ERROR);
        }
    }//GEN-LAST:event_newButtonActionPerformed

    private void deleteButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteButtonActionPerformed
        UnitConfig sceneUnitConfig = ((SceneUnitConfigHolder) sceneSelectionComboBox.getSelectedItem()).getConfig();
        if (sceneUnitConfig.hasId() && !sceneUnitConfig.getId().isEmpty()) {
            try {
                lastSelected = null;
                Registries.getUnitRegistry().removeUnitConfig(sceneUnitConfig);
            } catch (CouldNotPerformException ex) {
                ExceptionPrinter.printHistory(ex, logger, LogLevel.WARN);
            }
        }
    }//GEN-LAST:event_deleteButtonActionPerformed

    private void applyUpdateButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_applyUpdateButtonActionPerformed
        if (lastSelected == null) {
            return;
        }

        // TODO: add statusPanel update?
        logger.info("Apply update...");
        SceneRemote sceneRemote = new SceneRemote();
        try {
            sceneRemote.init(lastSelected);
            applyUpdateButton.setBackground(Color.GRAY);
            sceneRemote.activate();
            sceneRemote.waitForData();
            try {
                sceneRemote.setActivationState(
                        ActivationState.newBuilder().setValue(ActivationState.State.ACTIVE).build()).get();
            } catch (ExecutionException ex) {
                throw new CouldNotPerformException("Could not activate scene [" + sceneRemote.getLabel() + "]", ex);
            }
        } catch (InterruptedException | CouldNotPerformException ex) {
            logger.warn("Could not apply update. Initialization and activation of scene remote failed!");
        }
    }//GEN-LAST:event_applyUpdateButtonActionPerformed

    public void addObserver(Observer<SceneConfig> observer) {
        observable.addObserver(observer);
    }

    public void removeObserver(Observer<SceneConfig> observer) {
        observable.removeObserver(observer);
    }

    private static class SceneUnitConfigHolder implements Comparable<SceneUnitConfigHolder> {

        private final UnitConfig config;

        public SceneUnitConfigHolder(UnitConfig config) {
            this.config = config;
        }

        @Override
        public String toString() {
            if (isNotSpecified()) {
                return "New";
            }
            try {
                return LabelProcessor.getBestMatch(config.getLabel());
            } catch (NotAvailableException e) {
                return "?";
            }
        }

        public boolean isNotSpecified() {
            return config == null;
        }

        public UnitConfig getConfig() {
            return config;
        }

        public String getSceneId() throws CouldNotPerformException {
            try {
                if (config == null) {
                    throw new NotAvailableException("messageOrBuilder");
                }
                String id = config.getId();
                if (id.isEmpty()) {
                    throw new VerificationFailedException("Detected id is empty!");
                }
                return id;
            } catch (NotAvailableException | VerificationFailedException ex) {
                throw new CouldNotPerformException("Could not detect id.", ex);
            }
        }

        @Override
        public int compareTo(SceneUnitConfigHolder o) {
            return toString().compareTo(o.toString());
        }

        @Override
        public boolean equals(final Object obj) {
            if (obj instanceof SceneUnitConfigHolder) {
                final SceneUnitConfigHolder other = (SceneUnitConfigHolder) obj;
                try {
                    return new EqualsBuilder().append(getSceneId(), other.getSceneId()).isEquals();
                } catch (CouldNotPerformException ex) {
                    return new EqualsBuilder().append(getConfig(), other.getConfig()).isEquals();
                }
            } else {
                return false;
            }
        }

        @Override
        public int hashCode() {
            try {
                return new HashCodeBuilder().append(getSceneId()).toHashCode();
            } catch (CouldNotPerformException ex) {
                return new HashCodeBuilder().append(config).toHashCode();
            }
        }
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton applyUpdateButton;
    private javax.swing.JButton deleteButton;
    private org.openbase.bco.manager.scene.visual.LocationSelectorPanel locationSelectorPanel;
    private javax.swing.JButton newButton;
    private javax.swing.JComboBox sceneSelectionComboBox;
    // End of variables declaration//GEN-END:variables
}