/******************************************************************************* * 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.ide.spd.internal.ui.handlers; import gov.redhawk.eclipsecorba.idl.IdlInterfaceDcl; import gov.redhawk.eclipsecorba.library.IdlLibrary; import gov.redhawk.ide.spd.internal.ui.editor.ComponentEditor; import gov.redhawk.model.sca.util.ModelUtil; import java.util.HashSet; import java.util.Map; import java.util.Set; import mil.jpeojtrs.sca.scd.AbstractPort; import mil.jpeojtrs.sca.scd.InheritsInterface; import mil.jpeojtrs.sca.scd.Interface; import mil.jpeojtrs.sca.scd.PortType; import mil.jpeojtrs.sca.scd.Ports; import mil.jpeojtrs.sca.scd.Provides; import mil.jpeojtrs.sca.scd.ScdFactory; import mil.jpeojtrs.sca.scd.ScdPackage; import mil.jpeojtrs.sca.spd.SoftPkg; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.emf.common.command.Command; import org.eclipse.emf.common.command.CompoundCommand; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.edit.command.AddCommand; import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.ui.handlers.HandlerUtil; /** * An implementation of {@link AbstractHandler} for adding a port to a SoftwareComponent. * @since 6.0 */ public class AddPortHandler extends AbstractHandler { private static final String DEFAULT_PORT_REP_ID = "IDL:BULKIO/dataFloat:1.0"; private static final String DEFAULT_PORT_NAME = "dataFloat"; private EditingDomain editingDomain; private Resource resource; private SoftPkg softPkg; private ComponentEditor editor; private Map<String, Interface> interfaceMap; public AddPortHandler() { } /** * Constructor for use within the package so this handler can be used by other handlers. * * @param editingDomain * @param resource * @param softPkg */ public AddPortHandler(final EditingDomain editingDomain, final Resource resource, final SoftPkg softPkg) { this.editingDomain = editingDomain; this.resource = resource; this.softPkg = softPkg; this.interfaceMap = PortsHandlerUtil.getInterfaceMap(this.softPkg); } /** * {@inheritDoc} */ @Override public Object execute(final ExecutionEvent event) throws ExecutionException { this.editor = (ComponentEditor) HandlerUtil.getActiveEditor(event); this.editingDomain = this.editor.getEditingDomain(); this.resource = this.editor.getMainResource(); this.softPkg = ModelUtil.getSoftPkg(this.resource); this.interfaceMap = PortsHandlerUtil.getInterfaceMap(this.softPkg); // Creates a new port with default settings Command defaultPortCommand = createDefaultAddPortCommand(editor.getIdlLibrary()); this.editingDomain.getCommandStack().execute(defaultPortCommand); return null; } /** * Adds the port and any associated interfaces. */ public Command createDefaultAddPortCommand(final IdlLibrary library) { String defaultRepID = DEFAULT_PORT_REP_ID; Provides provides = ScdFactory.eINSTANCE.createProvides(); provides.setName(getDefaultName(getPorts())); provides.setRepID(defaultRepID); provides.getPortType().add(ScdFactory.eINSTANCE.createPortTypeContainer(PortType.DATA)); final CompoundCommand command = new CompoundCommand("Add Default Port Command"); command.append(AddCommand.create(this.editingDomain, PortsHandlerUtil.getPorts(this.softPkg), ScdPackage.Literals.PORTS__PROVIDES, provides)); if (!this.interfaceMap.containsKey(defaultRepID)) { command.append(createAddInterfaceCommand(library, defaultRepID, this.interfaceMap)); } return command; } private String getDefaultName(Ports ports) { String defaultName = DEFAULT_PORT_NAME; Set<String> portNameList = new HashSet<String>(); for (AbstractPort port : ports.getAllPorts()) { portNameList.add(port.getName()); } int nameIncrement = 1; while (portNameList.contains(defaultName)) { defaultName = DEFAULT_PORT_NAME + "_" + nameIncrement++; } return (defaultName.toString()); } /** * Creates a command to add the interface and all inherited interfaces provided they're not already in the * interfaceMap. * * @param repId the {@link String} repId of the {@link Interface} to add * @param interfaceMap the {@link Map} of current interfaces * @return the {@link Command} to add the specified {@link Interface} and all {@link InheritsInterface} if they * don't already exist and are present in the {@link IdlLibrary}; <code> null </code> otherwise */ public Command createAddInterfaceCommand(final IdlLibrary library, final String repId, final Map<String, Interface> interfaceMap) { final Interface i = ScdFactory.eINSTANCE.createInterface(); final IdlInterfaceDcl idlInter = (IdlInterfaceDcl) library.find(repId); // If the interface isn't present in the IdlLibrary, there's nothing to do if (idlInter != null) { final CompoundCommand command = new CompoundCommand("Add Interfaces"); i.setName(idlInter.getName()); i.setRepid(repId); // Add all the inherited interfaces first. for (final IdlInterfaceDcl inherited : idlInter.getInheritedInterfaces()) { final InheritsInterface iface = ScdFactory.eINSTANCE.createInheritsInterface(); iface.setRepid(inherited.getRepId()); i.getInheritsInterfaces().add(iface); // If the inherited interface isn't already present, make a recursive call to add it. if (!interfaceMap.containsKey(inherited.getRepId())) { command.append(createAddInterfaceCommand(library, inherited.getRepId(), interfaceMap)); } } // If the interface isn't already present if (!interfaceMap.containsKey(i.getRepid())) { interfaceMap.put(i.getRepid(), i); command.append(AddCommand.create(this.editingDomain, PortsHandlerUtil.getInterfaces(this.softPkg), ScdPackage.Literals.INTERFACES__INTERFACE, i)); } return command; } return null; } private Ports getPorts() { return PortsHandlerUtil.getPorts(this.softPkg); } }