/** * Copyright (c) 2011-2014, OpenIoT * * This file is part of OpenIoT. * * OpenIoT is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, version 3 of the License. * * OpenIoT 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with OpenIoT. If not, see <http://www.gnu.org/licenses/>. * * Contact: OpenIoT mailto: info@openiot.eu */ package org.openiot.ui.request.definition.web.model.nodes.impl.filters; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Observable; import java.util.Observer; import java.util.logging.Level; import org.openiot.ui.request.commons.annotations.Endpoint; import org.openiot.ui.request.commons.annotations.Endpoints; import org.openiot.ui.request.commons.annotations.GraphNodeClass; import org.openiot.ui.request.commons.annotations.NodeProperties; import org.openiot.ui.request.commons.annotations.NodeProperty; import org.openiot.ui.request.commons.interfaces.GraphModel; import org.openiot.ui.request.commons.logging.LoggerService; import org.openiot.ui.request.commons.nodes.base.DefaultGraphNode; import org.openiot.ui.request.commons.nodes.base.DefaultGraphNodeEndpoint; import org.openiot.ui.request.commons.nodes.enums.AnchorType; import org.openiot.ui.request.commons.nodes.enums.ConnectorType; import org.openiot.ui.request.commons.nodes.enums.EndpointType; import org.openiot.ui.request.commons.nodes.enums.PropertyType; import org.openiot.ui.request.commons.nodes.interfaces.GraphNode; import org.openiot.ui.request.commons.nodes.interfaces.GraphNodeConnection; import org.openiot.ui.request.commons.nodes.interfaces.GraphNodeEndpoint; import org.openiot.ui.request.commons.nodes.interfaces.GraphNodeEventListener; import org.openiot.ui.request.definition.web.model.nodes.impl.sources.GenericSource; import org.openiot.ui.request.definition.web.util.EndpointListLabelOrderComparator; /** * * @author Achilleas Anagnostopoulos (aanag) email: aanag@sensap.eu */ @GraphNodeClass(label = "Group", type = "FILTER", scanProperties = true) @Endpoints({ @Endpoint(type = EndpointType.Input, anchorType = AnchorType.Left, scope = "sensor_Number sensor_Integer sensor_Long sensor_Double sensor_Float", label = "ATTRIBUTES", maxConnections = -1, required = true) }) @NodeProperties({ @NodeProperty(type = PropertyType.Writable, javaType = java.util.ArrayList.class, name = "GROUPS", required = true) }) public class Group extends DefaultGraphNode implements GraphNodeEventListener, Serializable, Observer { private static final long serialVersionUID = 1L; public Group() { super(); addPropertyChangeObserver(this); } protected void removeAllGroups() { Iterator<GraphNodeEndpoint> endpointIt = this.getEndpointDefinitions().iterator(); while (endpointIt.hasNext()) { GraphNodeEndpoint endpoint = endpointIt.next(); if (endpoint.getLabel().startsWith("grp_")) { disconnectEndpoint(endpoint); endpointIt.remove(); } else if (endpoint.getScope().startsWith("sensor_")) { disconnectEndpoint(endpoint); endpoint.setScope(endpoint.getScope().replace("sensor_", "")); } } } protected void addGroups(List<String> srcEndpointLabels) { // If an empty list is passed, remove all groups if (srcEndpointLabels == null || srcEndpointLabels.isEmpty()) { removeAllGroups(); return; } // Operate on a copy of the input list List<String> newEndpointLabels = new ArrayList<String>(srcEndpointLabels); List<String> goneEndpointLabels = new ArrayList<String>(); Iterator<GraphNodeEndpoint> endpointIt = this.getEndpointDefinitions().iterator(); while (endpointIt.hasNext()) { GraphNodeEndpoint endpoint = endpointIt.next(); // Ignore non group endpoints if (!endpoint.getLabel().contains("recordTime")) { continue; } String label = endpoint.getLabel().replace("grp_", ""); if (newEndpointLabels.contains(label)) { newEndpointLabels.remove(label); } else { goneEndpointLabels.add(endpoint.getLabel()); } } // Remove gone endpoints for (String goneLabel : goneEndpointLabels) { GraphNodeEndpoint ep = getEndpointByLabel(goneLabel); disconnectEndpoint(ep); getEndpointDefinitions().remove(ep); } // And new end point for each new group for (String srcEndpointLabel : newEndpointLabels) { GraphNodeEndpoint dst = new DefaultGraphNodeEndpoint(); dst.setType(EndpointType.Output); dst.setAnchor(AnchorType.Right); dst.setConnectorType(ConnectorType.Dot); dst.setScope("grp_Date"); dst.setLabel("grp_" + srcEndpointLabel); dst.setRequired(false); dst.setMaxConnections(-1); getEndpointDefinitions().add(0, dst); } // Finally sort all endpoints using the input list label indices Collections.sort(getEndpointDefinitions(), new EndpointListLabelOrderComparator(srcEndpointLabels)); } @SuppressWarnings("unchecked") public void update(Observable o, Object modifiedKey) { if ((modifiedKey != null) && ("GROUPS".equals((String) modifiedKey))) { addGroups((List<String>) getPropertyValueMap().get("GROUPS")); } } public void onNodeConnected(GraphModel model, GraphNode otherNode, GraphNodeEndpoint otherNodeEndpoint, GraphNodeEndpoint thisNodeEndpoint) { if(!"ATTRIBUTES".equals(thisNodeEndpoint.getLabel())){ return; } GraphNodeEndpoint dst = new DefaultGraphNodeEndpoint(); dst.setType(EndpointType.Output); dst.setAnchor(AnchorType.Right); dst.setConnectorType(ConnectorType.Rectangle); dst.setScope("grp_" + otherNodeEndpoint.getScope().replace("sensor_", "")); dst.setLabel("grp_" + otherNodeEndpoint.getLabel()); dst.setRequired(true); getEndpointDefinitions().add(dst); } public void onNodeDisconnected(GraphModel model, GraphNode otherNode, GraphNodeEndpoint otherNodeEndpoint, GraphNodeEndpoint thisNodeEndpoint) { if(!"ATTRIBUTES".equals(thisNodeEndpoint.getLabel())){ return; } // Remove output endpoint String label = "grp_" + otherNodeEndpoint.getLabel(); GraphNodeEndpoint ep = this.getEndpointByLabel(label); if( ep != null ){ getEndpointDefinitions().remove(ep); } } public void onNodeDeleted(GraphModel model) { } }