/******************************************************************************* * 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.ui.ComponentUiPlugin; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import mil.jpeojtrs.sca.scd.InheritsInterface; import mil.jpeojtrs.sca.scd.Interface; import mil.jpeojtrs.sca.scd.Interfaces; import mil.jpeojtrs.sca.scd.Ports; import mil.jpeojtrs.sca.scd.Provides; import mil.jpeojtrs.sca.scd.ScdDocumentRoot; import mil.jpeojtrs.sca.scd.ScdFactory; import mil.jpeojtrs.sca.scd.SoftwareComponent; import mil.jpeojtrs.sca.scd.Uses; import mil.jpeojtrs.sca.spd.SoftPkg; import mil.jpeojtrs.sca.spd.SpdDocumentRoot; import mil.jpeojtrs.sca.util.ScaResourceFactoryUtil; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.commands.IHandler; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature.Setting; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.handlers.HandlerUtil; import org.eclipse.ui.progress.IWorkbenchSiteProgressService; /** * @since 6.0 */ public class OrganizeInterfacesHandler extends AbstractHandler implements IHandler { private class CleanUpJob extends Job { /** * @param name */ public CleanUpJob() { super("Clean Up Component Files Job"); } /** * {@inheritDoc} */ @Override protected IStatus run(final IProgressMonitor monitor) { for (final Object obj : OrganizeInterfacesHandler.this.fSelection.toArray()) { if (obj instanceof IFile) { final IFile file = (IFile) obj; final ResourceSet set = ScaResourceFactoryUtil.createResourceSet(); final Resource tempRes = set.getResource(URI.createPlatformResourceURI(file.getFullPath().toString(), true), true); // Load the resource and get the root object try { tempRes.load(null); } catch (final IOException e1) { return new Status(IStatus.ERROR, ComponentUiPlugin.PLUGIN_ID, "Failed to clean up Component Files in " + file.getName(), e1); } final EObject eObj = tempRes.getEObject("/"); // Get the SCD, either through the SPD or from the SCD file if (eObj instanceof SoftPkg) { final SoftPkg spd = (SoftPkg) eObj; OrganizeInterfacesHandler.this.resource = spd.getDescriptor().getComponent(); } else if (eObj instanceof SoftwareComponent) { OrganizeInterfacesHandler.this.resource = (SoftwareComponent) eObj; } else if (eObj instanceof SpdDocumentRoot) { final SpdDocumentRoot root = (SpdDocumentRoot) eObj; OrganizeInterfacesHandler.this.resource = root.getSoftpkg().getDescriptor().getComponent(); } else if (eObj instanceof ScdDocumentRoot) { final ScdDocumentRoot root = (ScdDocumentRoot) eObj; OrganizeInterfacesHandler.this.resource = root.getSoftwarecomponent(); } else { continue; } // Load the IDL library, used for adding missing interfaces try { OrganizeInterfacesHandler.this.loadIdlLibrary(monitor, file.getProject()); } catch (final CoreException e1) { ComponentUiPlugin.logException(e1, "Unable to load IDL Library, cannot organize interfaces."); } // Get the list of interfaces and port Rep IDs final EList<Interface> interfaces = OrganizeInterfacesHandler.this.resource.getInterfaces().getInterface(); final Ports ports = getPorts(); final HashSet<String> ints = new HashSet<String>(); for (final Provides p : ports.getProvides()) { ints.add(p.getRepID()); } for (final Uses u : ports.getUses()) { ints.add(u.getRepID()); } // Add any missing port interfaces for (final String repId : ints) { // Only add the interface if it's not already there. if (!hasInterface(repId)) { addInterface(repId, interfaces); } } // Check each interface in the list to see if it's still // used, remove it if not. final List<Interface> badIfaces = new ArrayList<Interface>(); for (final Interface inter : interfaces) { final Collection<Setting> references = EcoreUtil.UsageCrossReferencer.find(inter, inter.eResource()); if (references.size() == 0) { badIfaces.add(inter); } } // Remove any unused interfaces interfaces.removeAll(badIfaces); // Save the modified SCD resource try { OrganizeInterfacesHandler.this.resource.eResource().save(null); } catch (final IOException e) { ComponentUiPlugin.logException(e, "Unable to save resource after organizing interfaces"); } } } return Status.OK_STATUS; } } private IStructuredSelection fSelection; private SoftwareComponent resource; private IdlLibrary idlLibrary; private IWorkbenchSiteProgressService getActiveProgressService() { IWorkbenchSiteProgressService service = null; if (PlatformUI.isWorkbenchRunning()) { final IWorkbenchWindow activeWorkbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (activeWorkbenchWindow != null) { final IWorkbenchPage activePage = activeWorkbenchWindow.getActivePage(); if (activePage != null) { final IWorkbenchPart activePart = activePage.getActivePart(); if (activePart != null) { service = (IWorkbenchSiteProgressService) activePart.getSite().getAdapter(IWorkbenchSiteProgressService.class); } } } } return service; } @Override public Object execute(final ExecutionEvent event) throws ExecutionException { final ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event).getSelectionService().getSelection(); if (selection instanceof IStructuredSelection) { this.fSelection = (IStructuredSelection) selection; } if (this.fSelection != null && !this.fSelection.isEmpty()) { final Job job = getJob(); if (job != null) { final IWorkbenchSiteProgressService progressService = getActiveProgressService(); if (progressService != null) { progressService.schedule(job); } else { job.schedule(); } } } return null; } /** * @return */ private Job getJob() { return new CleanUpJob(); } /** * This method checks if there is an interface with the specified RepID. * * @param repId the Rep ID to check */ private boolean hasInterface(final String repId) { final Interfaces ints = this.resource.getInterfaces(); for (final EObject e : ints.eContents()) { if (repId.equals(((Interface) e).getRepid())) { return true; } } return false; } /** * This method returns an interface, corresponding to the passed in Rep ID, * to add to the interface list. It recurses itself adding missing inherits * interfaces. * * @param newRep the Rep ID to add * @param interfaces the interfaces object to add the interface to */ private void addInterface(final String repId, final EList<Interface> interfaces) { final Interface i = ScdFactory.eINSTANCE.createInterface(); final IdlInterfaceDcl idlInter = (IdlInterfaceDcl) this.idlLibrary.find(repId); // Make sure we found the interface object if (idlInter != null) { i.setName(idlInter.getName()); i.setRepid(repId); // Loop through the inherited interfaces for this interface and add // any required interfaces for (final IdlInterfaceDcl inherited : idlInter.getInheritedInterfaces()) { final InheritsInterface iface = ScdFactory.eINSTANCE.createInheritsInterface(); iface.setRepid(inherited.getRepId()); i.getInheritsInterfaces().add(iface); addInterface(inherited.getRepId(), interfaces); } interfaces.add(i); } } /** * This method returns the list of ports for the component. * * @return the list of ports */ private Ports getPorts() { return this.resource.getComponentFeatures().getPorts(); } /** * This method loads the IDL library from the current project. * * @param monitor the progress monitor to show loading progress * @param project the project to load the IDL for * @throws CoreException */ public IdlLibrary loadIdlLibrary(final IProgressMonitor monitor, final IProject project) throws CoreException { if (this.idlLibrary == null) { final ResourceSet set = ScaResourceFactoryUtil.createResourceSet(); final IFile libraryFile = project.getFile(".library"); if (libraryFile.exists()) { final Resource res = set.getResource(URI.createPlatformResourceURI(libraryFile.getFullPath().toString(), true), true); final EObject obj = res.getEObject("/"); if (obj instanceof IdlLibrary) { this.idlLibrary = (IdlLibrary) obj; this.idlLibrary.load(monitor); } } } return this.idlLibrary; } }