/******************************************************************************* * 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.sad.internal.ui.properties.model; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import org.eclipse.emf.common.command.Command; import org.eclipse.emf.common.command.UnexecutableCommand; import org.eclipse.emf.common.notify.AdapterFactory; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.util.FeatureMap; import org.eclipse.emf.edit.command.AddCommand; import org.eclipse.emf.edit.command.RemoveCommand; import org.eclipse.emf.edit.command.SetCommand; import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.emf.edit.provider.ITreeItemContentProvider; import org.eclipse.emf.edit.provider.ItemProviderAdapter; import org.eclipse.emf.edit.provider.ViewerNotification; import org.eclipse.emf.transaction.util.TransactionUtil; import gov.redhawk.sca.util.PluginUtil; import mil.jpeojtrs.sca.partitioning.ComponentFile; import mil.jpeojtrs.sca.partitioning.ComponentProperties; import mil.jpeojtrs.sca.partitioning.PartitioningFactory; import mil.jpeojtrs.sca.partitioning.PartitioningPackage; import mil.jpeojtrs.sca.prf.AbstractProperty; import mil.jpeojtrs.sca.prf.AbstractPropertyRef; import mil.jpeojtrs.sca.prf.PrfPackage; import mil.jpeojtrs.sca.prf.Properties; import mil.jpeojtrs.sca.prf.Simple; import mil.jpeojtrs.sca.prf.SimpleSequence; import mil.jpeojtrs.sca.prf.Struct; import mil.jpeojtrs.sca.prf.StructSequence; import mil.jpeojtrs.sca.sad.AssemblyController; import mil.jpeojtrs.sca.sad.ExternalProperties; import mil.jpeojtrs.sca.sad.ExternalProperty; import mil.jpeojtrs.sca.sad.SadComponentInstantiation; import mil.jpeojtrs.sca.sad.SoftwareAssembly; import mil.jpeojtrs.sca.spd.SoftPkg; import mil.jpeojtrs.sca.spd.SpdPackage; import mil.jpeojtrs.sca.util.ScaEcoreUtils; public class SadPropertiesComponent extends ItemProviderAdapter implements ITreeItemContentProvider, NestedItemProvider { private static final EStructuralFeature[] PATH = new EStructuralFeature[] { SpdPackage.Literals.SOFT_PKG__PROPERTY_FILE, SpdPackage.Literals.PROPERTY_FILE__PROPERTIES }; private SadComponentInstantiation compInst; public SadPropertiesComponent(AdapterFactory adapterFactory, SadComponentInstantiation compInst) { super(adapterFactory); this.compInst = compInst; propertiesAdded(compInst.getComponentProperties()); } @Override public Object getParent(Object object) { return getSoftwareAssembly(); } @Override protected Object getValue(EObject eObject, EStructuralFeature eStructuralFeature) { if (eStructuralFeature == PrfPackage.Literals.PROPERTIES__PROPERTIES) { ComponentFile theCompFile = ((SadComponentInstantiation) eObject).getPlacement().getComponentFileRef().getFile(); // The component file can be null if the component file reference does not map back to any SPD (likely due // to a copy paste error on the users part) if (theCompFile != null && theCompFile.getSoftPkg() != null) { SoftPkg spd = theCompFile.getSoftPkg(); Properties properties = ScaEcoreUtils.getFeature(spd, SadPropertiesComponent.PATH); if (properties != null) { return properties.getProperties(); } } return Collections.EMPTY_LIST; } return super.getValue(eObject, eStructuralFeature); } @Override protected Collection< ? extends EStructuralFeature> getChildrenFeatures(Object object) { if (childrenFeatures == null) { childrenFeatures = new ArrayList<EStructuralFeature>(); childrenFeatures.add(PrfPackage.Literals.PROPERTIES__PROPERTIES); } return childrenFeatures; } @Override protected Object createWrapper(EObject object, EStructuralFeature feature, Object value, int index) { if (feature == PrfPackage.Literals.PROPERTIES__PROPERTIES) { FeatureMap.Entry entry = (FeatureMap.Entry) value; SadPropertyImpl< ? > property = createViewerProperty((AbstractProperty) entry.getValue()); ExternalProperty externalProperty = getExternalProperty(property.getID()); property.setExternalProperty(externalProperty); return property; } return super.createWrapper(object, feature, value, index); } public SoftwareAssembly getSoftwareAssembly() { return ScaEcoreUtils.getEContainerOfType(compInst, SoftwareAssembly.class); } public SadComponentInstantiation getComponentInstantiation() { return compInst; } public boolean isAssemblyController() { SoftwareAssembly softwareAssembly = getSoftwareAssembly(); if (softwareAssembly.getAssemblyController() != null) { AssemblyController assemblyController = softwareAssembly.getAssemblyController(); if (assemblyController.getComponentInstantiationRef() != null) { if (PluginUtil.equals(compInst.getId(), assemblyController.getComponentInstantiationRef().getRefid())) { return true; } } } return false; } private SadPropertyImpl< ? > createViewerProperty(AbstractProperty def) { switch (def.eClass().getClassifierID()) { case PrfPackage.SIMPLE: return new SadPropertiesSimple(adapterFactory, (Simple) def, this); case PrfPackage.SIMPLE_SEQUENCE: return new SadPropertiesSimpleSequence(adapterFactory, (SimpleSequence) def, this); case PrfPackage.STRUCT: return new SadPropertiesStruct(adapterFactory, (Struct) def, this); case PrfPackage.STRUCT_SEQUENCE: return new SadPropertiesStructSequence(adapterFactory, (StructSequence) def, this); default: return null; } } private ExternalProperty getExternalProperty(final String refId) { final ExternalProperties properties = getSoftwareAssembly().getExternalProperties(); if (properties != null) { for (final ExternalProperty property : properties.getProperties()) { if (property.getCompRefID().equals(compInst.getId()) && property.getPropID().equals(refId)) { return property; } } } return null; } @Override public EditingDomain getEditingDomain() { return TransactionUtil.getEditingDomain(getSoftwareAssembly()); } @Override protected EStructuralFeature getChildFeature(Object object, Object child) { switch (((EObject) child).eClass().getClassifierID()) { case PrfPackage.SIMPLE_REF: return PartitioningPackage.Literals.COMPONENT_PROPERTIES__SIMPLE_REF; case PrfPackage.SIMPLE_SEQUENCE_REF: return PartitioningPackage.Literals.COMPONENT_PROPERTIES__SIMPLE_SEQUENCE_REF; case PrfPackage.STRUCT_REF: return PartitioningPackage.Literals.COMPONENT_PROPERTIES__STRUCT_REF; case PrfPackage.STRUCT_SEQUENCE_REF: return PartitioningPackage.Literals.COMPONENT_PROPERTIES__STRUCT_SEQUENCE_REF; default: return null; } } @Override public Command createAddChildCommand(EditingDomain domain, Object child, EStructuralFeature feature) { if (feature == SadPropertiesPackage.Literals.SAD_PROPERTY__VALUE) { SadComponentInstantiation instantiation = getComponentInstantiation(); ComponentProperties properties = instantiation.getComponentProperties(); if (properties == null) { properties = PartitioningFactory.eINSTANCE.createComponentProperties(); properties.getProperties().add(getChildFeature(properties, child), child); return SetCommand.create(domain, instantiation, PartitioningPackage.Literals.COMPONENT_INSTANTIATION__COMPONENT_PROPERTIES, properties); } else { return AddCommand.create(domain, properties, getChildFeature(properties, child), child); } } return UnexecutableCommand.INSTANCE; } @Override public Command createRemoveChildCommand(EditingDomain domain, Object child, EStructuralFeature feature) { if (feature == SadPropertiesPackage.Literals.SAD_PROPERTY__VALUE) { ComponentProperties properties = getComponentInstantiation().getComponentProperties(); if (properties.getProperties().size() == 1) { return RemoveCommand.create(domain, properties); } else { return RemoveCommand.create(domain, properties, getChildFeature(properties, child), child); } } return UnexecutableCommand.INSTANCE; } @Override public void notifyChanged(Notification msg) { final Object feature = msg.getFeature(); if (feature == PartitioningPackage.Literals.COMPONENT_INSTANTIATION__COMPONENT_PROPERTIES) { if (msg.getEventType() == Notification.SET) { ComponentProperties properties = (ComponentProperties) msg.getNewValue(); if (properties == null) { propertiesRemoved((ComponentProperties) msg.getOldValue()); } else { propertiesAdded(properties); } fireNotifyChanged(msg); } } else if (feature == PartitioningPackage.Literals.COMPONENT_PROPERTIES__PROPERTIES) { if (msg.getEventType() == Notification.ADD) { propertyChanged(unwrapProperty(msg.getNewValue()), msg); } else if (msg.getEventType() == Notification.REMOVE) { propertyChanged(unwrapProperty(msg.getOldValue()), msg); } } } private AbstractPropertyRef< ? > unwrapProperty(Object value) { if (value != null) { FeatureMap.Entry entry = (FeatureMap.Entry) value; return (AbstractPropertyRef< ? >) entry.getValue(); } return null; } @Override public boolean isAdapterForType(Object type) { if (type instanceof Class< ? >) { return ((Class< ? >) type).isInstance(this); } return super.isAdapterForType(type); } protected SadPropertyImpl< ? > getProperty(String identifier) { for (Object child : getChildren(compInst)) { SadPropertyImpl< ? > property = (SadPropertyImpl< ? >) child; if (property.getID().equals(identifier)) { return property; } } return null; } private void propertiesAdded(ComponentProperties properties) { if (properties != null) { properties.eAdapters().add(this); for (FeatureMap.Entry entry : properties.getProperties()) { AbstractPropertyRef< ? > ref = (AbstractPropertyRef< ? >) entry.getValue(); SadPropertyImpl< ? > property = getProperty(ref.getRefID()); if (property != null) { property.setReference(ref); } } } } private void propertiesRemoved(ComponentProperties properties) { if (properties != null) { properties.eAdapters().remove(this); for (FeatureMap.Entry entry : properties.getProperties()) { AbstractPropertyRef< ? > ref = (AbstractPropertyRef< ? >) entry.getValue(); SadPropertyImpl< ? > property = getProperty(ref.getRefID()); if (property != null) { property.setReference(null); } } } } private void propertyChanged(AbstractPropertyRef< ? > ref, Notification msg) { SadPropertyImpl< ? > property = getProperty(ref.getRefID()); if (property != null) { property.setReference(unwrapProperty(msg.getNewValue())); boolean contentRefresh = property.hasChildren(); fireNotifyChanged(new ViewerNotification(msg, property, contentRefresh, true)); } } }