/** * 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.sca.dcd.validation; import java.util.HashMap; import mil.jpeojtrs.sca.dcd.DcdComponentInstantiation; import mil.jpeojtrs.sca.dcd.DcdConnectInterface; import mil.jpeojtrs.sca.dcd.DcdConnections; import mil.jpeojtrs.sca.dcd.DcdPackage; import mil.jpeojtrs.sca.dcd.DcdProvidesPort; import mil.jpeojtrs.sca.dcd.DcdUsesPort; import mil.jpeojtrs.sca.partitioning.ComponentSupportedInterface; import mil.jpeojtrs.sca.partitioning.ComponentSupportedInterfaceStub; import mil.jpeojtrs.sca.partitioning.FindByStub; import mil.jpeojtrs.sca.partitioning.ProvidesPortStub; import mil.jpeojtrs.sca.validator.EnhancedConstraintStatus; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.validation.AbstractModelConstraint; import org.eclipse.emf.validation.IValidationContext; import org.eclipse.emf.validation.model.ConstraintStatus; public class ConnectionsConstraint extends AbstractModelConstraint { public static final String SOURCE_ID = DcdValidationConstants.SOURCE_ID; public static final int STATUS_CODE = 1002; /** * {@inheritDoc} */ @Override public IStatus validate(final IValidationContext ctx) { final EObject target = ctx.getTarget(); if (target instanceof DcdConnections) { final DcdConnections connections = (DcdConnections) target; return ConnectionsConstraint.validate(connections, ctx); } return Status.OK_STATUS; } /** * Validate whether or not there are any duplicate connect interfaces contained in the connections container * @param connections The container that holds all connect interfaces found in the node * @param ctx The validation context which we shall report our results to * @return IStatus Return OK Status if the connection container holds no duplicates or throw failure notice if it does */ public static IStatus validate(final DcdConnections connections, final IValidationContext ctx) { final HashMap<String, Integer> idsMap = new HashMap<String, Integer>(); final HashMap<String, DcdConnectInterface> connectMap = new HashMap<String, DcdConnectInterface>(); if (connections.getConnectInterface().size() > 0) { for (final DcdConnectInterface connect : connections.getConnectInterface()) { if (connect.getSource() != null && connect.getTarget() != null) { if (connect.getSource().eContainer() instanceof FindByStub || connect.getTarget().eContainer() instanceof FindByStub) { continue; } final String uniqueName = ConnectionsConstraint.getUniqueName(connect); if (!idsMap.containsKey(uniqueName)) { idsMap.put(uniqueName, 0); } else { final int count = idsMap.get(uniqueName) + 1; idsMap.put(uniqueName, count); if (!connectMap.containsKey(uniqueName)) { connectMap.put(uniqueName, connect); } } } } if (connectMap.size() > 0) { return new EnhancedConstraintStatus((ConstraintStatus) ctx.createFailureStatus(ConnectionsConstraint.getMessage(idsMap, connectMap)), DcdPackage.Literals.DEVICE_CONFIGURATION__CONNECTIONS); } } return Status.OK_STATUS; } /** * Determine if the passed connect interface is unique in the node * @param conn The connection that we shall search for other instances of via its owning container * @return Boolean Whether or not the connect interface is unique */ public static boolean uniqueConnection(final DcdConnectInterface conn) { final String uniqueName = ConnectionsConstraint.getUniqueName(conn); int occurrences = 0; if (conn.eContainer() instanceof DcdConnections) { final DcdConnections connections = (DcdConnections) conn.eContainer(); if (connections.getConnectInterface().size() > 0) { for (final DcdConnectInterface connect : connections.getConnectInterface()) { if (ConnectionsConstraint.getUniqueName(connect).equals(uniqueName)) { occurrences++; } if (occurrences > 1) { return false; } } } } return true; } /** * Compile a warning message that details all duplicate connections found in the users' node * @param idsMap HashMap that pairs unique ids to the number of occurrences in the node * @param connectMap HashMap pair unique ids to connect interfaces * @return The message as a string */ private static String getMessage(final HashMap<String, Integer> idsMap, final HashMap<String, DcdConnectInterface> connectMap) { final StringBuffer retVal = new StringBuffer(); for (final String uniqueName : idsMap.keySet()) { if (retVal.toString().length() > 0) { retVal.append("\n"); } final DcdConnectInterface connect = connectMap.get(uniqueName); if (connect != null && connect.getSource() != null && connect.getTarget() != null) { final DcdUsesPort uses = connect.getUsesPort(); retVal.append(idsMap.get(uniqueName)); retVal.append(" extra occurrence(s) of connection between "); retVal.append(uses.getUsesIdentifier() + " port of "); retVal.append(uses.getComponentInstantiationRef().getInstantiation().getUsageName() + " device and "); if (connect.getTarget() instanceof ProvidesPortStub) { final DcdProvidesPort provides = connect.getProvidesPort(); retVal.append(provides.getProvidesIdentifier() + " port of "); retVal.append(provides.getComponentInstantiationRef().getInstantiation().getUsageName() + " device."); } else { final ComponentSupportedInterface inter = connect.getComponentSupportedInterface(); retVal.append(inter.getSupportedIdentifier() + " port of "); retVal.append(inter.getComponentInstantiationRef().getInstantiation().getUsageName() + " device."); } } } return retVal.toString(); } /** * Return unique name that is of pattern <source_port_name> <parent_component> <target_port_name> <target_parent_component> * @param connect The connect interface that we shall make a unique name for * @return String Return the unique name as a string */ private static String getUniqueName(final DcdConnectInterface connect) { final StringBuffer retVal = new StringBuffer(); if (connect.getSource() != null && connect.getSource().eContainer() instanceof DcdComponentInstantiation) { final DcdUsesPort uses = connect.getUsesPort(); retVal.append(uses.getUsesIdentifier() + " " + uses.getComponentInstantiationRef().getRefid() + " "); } if (connect.getTarget() != null) { if (connect.getTarget().eContainer() instanceof DcdComponentInstantiation) { if (connect.getTarget() instanceof ProvidesPortStub) { final DcdProvidesPort provides = connect.getProvidesPort(); retVal.append(provides.getProvidesIdentifier() + " " + provides.getComponentInstantiationRef().getRefid()); } else if (connect.getTarget() instanceof ComponentSupportedInterfaceStub) { final ComponentSupportedInterface inter = connect.getComponentSupportedInterface(); retVal.append(inter.getSupportedIdentifier() + " " + inter.getComponentInstantiationRef().getRefid()); } } } return retVal.toString(); } }