/**
* This file is protected by Copyright.
* Please refer to the COPYRIGHT file distributed with this source distribution.
*
* This file is part of REDHAWK IDE.
*
* 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.
*
*/
package gov.redhawk.model.sca.commands;
import gov.redhawk.model.sca.ScaFactory;
import gov.redhawk.model.sca.ScaPackage;
import gov.redhawk.model.sca.ScaPort;
import gov.redhawk.model.sca.ScaPortContainer;
import gov.redhawk.model.sca.ScaProvidesPort;
import gov.redhawk.model.sca.ScaUsesPort;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import mil.jpeojtrs.sca.scd.AbstractPort;
import mil.jpeojtrs.sca.scd.Provides;
import mil.jpeojtrs.sca.scd.Uses;
import org.eclipse.core.runtime.IStatus;
import org.omg.CORBA.Object;
/**
* @since 14.0
*/
public class MergePortsCommand extends SetStatusCommand<ScaPortContainer> {
public static class PortData {
private final AbstractPort portProfile;
private final org.omg.CORBA.Object portObj;
private String portName;
public PortData(AbstractPort portProfile, Object portObj) {
this(portProfile.getName(), portProfile, portObj);
}
/**
* @since 18.0
*/
public PortData(String portName, AbstractPort portProfile, Object portObj) {
super();
this.portProfile = portProfile;
this.portObj = portObj;
this.portName = portName;
}
public AbstractPort getPortProfile() {
return portProfile;
}
public org.omg.CORBA.Object getPortObj() {
return portObj;
}
}
private static class PortHash {
private final Class< ? > portType;
private final String name;
private final String ior;
public PortHash(PortData data) {
this.portType = data.portProfile.getClass();
this.name = data.portName;
if (data.portObj != null) {
this.ior = data.portObj.toString();
} else {
this.ior = null;
}
}
public PortHash(ScaPort< ? , ? > port) {
this.portType = port.getProfileObj().getClass();
this.name = port.getName();
this.ior = port.getIor();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((ior == null) ? 0 : ior.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((portType == null) ? 0 : portType.hashCode());
return result;
}
@Override
public boolean equals(java.lang.Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
PortHash other = (PortHash) obj;
if (ior == null) {
if (other.ior != null) {
return false;
}
} else if (!ior.equals(other.ior)) {
return false;
}
if (name == null) {
if (other.name != null) {
return false;
}
} else if (!name.equals(other.name)) {
return false;
}
if (portType == null) {
if (other.portType != null) {
return false;
}
} else if (!portType.equals(other.portType)) {
return false;
}
return true;
}
}
private List<PortData> newPorts;
public MergePortsCommand(ScaPortContainer portContainer, List<PortData> newPorts, IStatus status) {
super(portContainer, ScaPackage.Literals.SCA_PORT_CONTAINER__PORTS, status);
this.newPorts = newPorts;
}
/* (non-Javadoc)
* @see org.eclipse.emf.common.command.Command#execute()
*/
@Override
public void execute() {
// If status is not in error we can continue. Warnings may exist if UnknownPort exception was thrown
if (status.getSeverity() < IStatus.ERROR) {
Map<PortHash, ScaPort< ? , ? >> currentMap = new HashMap<PortHash, ScaPort< ? , ? >>();
for (ScaPort< ? , ? > port : provider.getPorts()) {
currentMap.put(new PortHash(port), port);
}
Map<PortHash, ScaPort< ? , ? >> removeMap = new HashMap<PortHash, ScaPort< ? , ? >>();
removeMap.putAll(currentMap);
Map<PortHash, PortData> newPortMap = new HashMap<PortHash, MergePortsCommand.PortData>();
for (PortData data : newPorts) {
newPortMap.put(new PortHash(data), data);
}
// Remove stale ports
removeMap.keySet().removeAll(newPortMap.keySet());
if (!removeMap.isEmpty() && !provider.getPorts().isEmpty()) {
provider.getPorts().removeAll(removeMap.values());
}
// Remove duplicate ports
newPortMap.keySet().removeAll(currentMap.keySet());
for (PortData data : newPortMap.values()) {
ScaPort< ? , ? > newPort = null;
if (data.portProfile instanceof Provides) {
ScaProvidesPort tmpPort = ScaFactory.eINSTANCE.createScaProvidesPort();
tmpPort.setProfileObj((Provides) data.portProfile);
newPort = tmpPort;
} else if (data.portProfile instanceof Uses) {
ScaUsesPort tmpPort = ScaFactory.eINSTANCE.createScaUsesPort();
tmpPort.setProfileObj((Uses) data.portProfile);
newPort = tmpPort;
}
if (newPort != null) {
newPort.setCorbaObj(data.portObj);
newPort.setName(data.portName);
provider.getPorts().add(newPort);
}
}
if (!provider.isSetPorts()) {
provider.getPorts().clear();
}
} else {
provider.unsetPorts();
}
super.execute();
}
}