/*******************************************************************************
* 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.ui.wizard;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
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.SubMonitor;
import org.eclipse.emf.common.util.EMap;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import gov.redhawk.ide.codegen.CodegenFactory;
import gov.redhawk.ide.codegen.CodegenUtil;
import gov.redhawk.ide.codegen.FileStatus;
import gov.redhawk.ide.codegen.FileToCRCMap;
import gov.redhawk.ide.codegen.ICodeGeneratorDescriptor;
import gov.redhawk.ide.codegen.IPropertyDescriptor;
import gov.redhawk.ide.codegen.IScaComponentCodegen;
import gov.redhawk.ide.codegen.ITemplateDesc;
import gov.redhawk.ide.codegen.ImplementationSettings;
import gov.redhawk.ide.codegen.Property;
import gov.redhawk.ide.codegen.RedhawkCodegenActivator;
import gov.redhawk.ide.codegen.WaveDevSettings;
import gov.redhawk.ide.ui.RedhawkIDEUiPlugin;
import gov.redhawk.ide.ui.wizard.RedhawkImportWizardPage1.ProjectRecord;
import mil.jpeojtrs.sca.spd.Implementation;
import mil.jpeojtrs.sca.spd.SoftPkg;
import mil.jpeojtrs.sca.util.ScaResourceFactoryUtil;
/**
* @since 9.1
*/
public abstract class RedhawkImportUtil {
private static String sadExtension = ".+\\.sad.xml";
private static String spdExtension = ".+\\.spd.xml";
private static String dcdExtension = ".+\\.dcd.xml";
protected abstract int findMissingFiles();
protected abstract IProject createDotProjectFile(String projectType);
protected abstract WaveDevSettings createWaveDevFile() throws CoreException;
public abstract SoftPkg getSoftPkg(String path);
public static String getSadExtension() {
return sadExtension;
}
public static String getSpdExtension() {
return spdExtension;
}
public static String getDcdExtension() {
return dcdExtension;
}
public void generateFiles(IProgressMonitor progressMonitor, String projectLocation, IProject importProject, WaveDevSettings importWaveDev)
throws CoreException {
final SubMonitor monitor = SubMonitor.convert(progressMonitor, 2);
final IProject project = importProject;
final SoftPkg softPkg = getSoftPkg(project);
if (softPkg == null) {
throw new IllegalStateException("Could not load spd.xml for project");
}
// Create or open the existing settings
final WaveDevSettings waveDev = importWaveDev;
if (waveDev == null) {
throw new IllegalStateException("Could not load wavedev settings for project");
}
final EMap<String, ImplementationSettings> implSet = waveDev.getImplSettings();
// Try generate each implementation, or just the specified language
for (final Implementation impl : softPkg.getImplementation()) {
final String currLang = impl.getProgrammingLanguage().getName();
// Prepare for generation
final ImplementationSettings settings = implSet.get(impl.getId());
final ArrayList<FileToCRCMap> crcMap = new ArrayList<FileToCRCMap>();
// Validate the settings name
final String implName = impl.getId();
if (!implName.equals(CodegenUtil.getValidName(implName))) {
System.err.println("Invalid characters in implementation name for " + implName); // SUPPRESS CHECKSTYLE INLINE
continue;
} else if (settings.getGeneratorId() != null) {
// Find the desired code generator
String codegenId = settings.getGeneratorId();
final ICodeGeneratorDescriptor codeGenDesc = RedhawkCodegenActivator.getCodeGeneratorsRegistry().findCodegen(codegenId);
if (codeGenDesc == null) {
System.err.println("The code generator(" + codegenId + ") for this implementation could not be found."); // SUPPRESS CHECKSTYLE INLINE
continue;
}
// Get the actual code generator
final IScaComponentCodegen generator = codeGenDesc.getGenerator();
// Get files to generate
final Set<FileStatus> fileStatusSet = generator.getGeneratedFilesStatus(settings, softPkg);
final Set<String> fileList = new HashSet<String>();
for (FileStatus s : fileStatusSet) {
fileList.add(s.getFilename());
}
// Create the files, shouldGenerate parameter should be false
final IStatus status = generator.generate(settings, impl, System.out, System.err, monitor.newChild(1), fileList.toArray(new String[0]), false,
crcMap);
// Save the workspace
final WorkspaceModifyOperation operation = new WorkspaceModifyOperation() {
@Override
protected void execute(final IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException {
final IStatus saveStatus = ResourcesPlugin.getWorkspace().save(true, monitor);
// Check the save results, hopefully this worked
if (!saveStatus.isOK()) {
System.err.println("Generated files, but there was a problem saving the workspace: " + saveStatus.getMessage()); //SUPPRESS CHECKSTYLE INLINE
}
}
};
try {
operation.run(monitor.newChild(1));
} catch (final InvocationTargetException e) {
throw new CoreException(new Status(IStatus.ERROR, RedhawkIDEUiPlugin.PLUGIN_ID, "Error saving resources", e));
} catch (final InterruptedException e) {
throw new CoreException(new Status(IStatus.ERROR, RedhawkIDEUiPlugin.PLUGIN_ID, "Error saving resources", e));
}
// Check the results
if (!status.isOK()) {
throw new CoreException(new Status(IStatus.ERROR, RedhawkIDEUiPlugin.PLUGIN_ID, "Errors occurred generating " + currLang + " code: " + status.getMessage()));
} else {
System.out.println("Done generating " + currLang + " code"); // SUPPRESS CHECKSTYLE INLINE
}
} else {
throw new CoreException(new Status(IStatus.ERROR, RedhawkIDEUiPlugin.PLUGIN_ID, "No generator specified for implementation: " + implName + ". No code generated."));
}
}
project.build(IncrementalProjectBuilder.FULL_BUILD, monitor.newChild(1));
}
private SoftPkg getSoftPkg(final IProject project) {
final ResourceSet set = ScaResourceFactoryUtil.createResourceSet();
final IFile softPkgFile = project.getFile(project.getName() + ".spd.xml");
final Resource resource = set.getResource(URI.createFileURI(softPkgFile.getLocation().toString()), true);
return SoftPkg.Util.getSoftPkg(resource);
}
/**
* @since 10.0
*/
protected WaveDevSettings createWaveDevFile(ProjectRecord projectRecord, String projectName, SoftPkg softPkg) throws CoreException {
WaveDevSettings waveDev = CodegenFactory.eINSTANCE.createWaveDevSettings();
// Recreate the basic settings for each implementation
// This makes assumptions that the defaults are selected for everything
for (final Implementation impl : softPkg.getImplementation()) {
final ImplementationSettings settings = CodegenFactory.eINSTANCE.createImplementationSettings();
final String lang = impl.getProgrammingLanguage().getName();
// Find the code generator if specified, otherwise pick the first one returned by the registry
ICodeGeneratorDescriptor codeGenDesc = null;
final ICodeGeneratorDescriptor[] codeGens = RedhawkCodegenActivator.getCodeGeneratorsRegistry().findCodegenByLanguage(lang);
if (codeGens.length > 0) {
codeGenDesc = codeGens[0];
}
if (codeGenDesc != null) {
final IScaComponentCodegen generator = codeGenDesc.getGenerator();
// Assume that there is <name>[/].+<other> format for the entrypoint
// Pick out <name> for both the output dir and settings name
final String lf = impl.getCode().getEntryPoint();
// Set the generator, settings name and output directory
settings.setGeneratorId(generator.getClass().getCanonicalName());
settings.setOutputDir(lf.substring(0, lf.lastIndexOf('/')));
// pick the first selectable and defaultable template returned by the registry
ITemplateDesc templateDesc = null;
final ITemplateDesc[] templates = RedhawkCodegenActivator.getCodeGeneratorTemplatesRegistry().findTemplatesByCodegen(settings.getGeneratorId());
for (final ITemplateDesc itd : templates) {
if (itd.isSelectable() && !itd.notDefaultableGenerator()) {
templateDesc = itd;
break;
}
}
// If we found the template, use it
if (templateDesc != null) {
// Set the properties to their default values
for (final IPropertyDescriptor prop : templateDesc.getPropertyDescriptors()) {
final Property p = CodegenFactory.eINSTANCE.createProperty();
p.setId(prop.getKey());
p.setValue(prop.getDefaultValue());
settings.getProperties().add(p);
}
settings.setTemplate(templateDesc.getId());
if (projectRecord.getTemplate() != null && !projectRecord.getTemplate().isEmpty()) {
settings.setTemplate(projectRecord.getTemplate().get(impl.getId()));
} else {
for (IRedhawkImportProjectWizardAssist assistant : RedhawkIDEUiPlugin.getDefault().getRedhawkImportWizardAssistants()) {
if (assistant.handlesLanguage(lang)) {
settings.setTemplate(assistant.getDefaultTemplate());
break;
}
}
}
}
}
for (IRedhawkImportProjectWizardAssist assistant : RedhawkIDEUiPlugin.getDefault().getRedhawkImportWizardAssistants()) {
if (assistant.handlesLanguage(lang)) {
assistant.setupWaveDev(projectName, settings);
break;
}
}
waveDev.getImplSettings().put(impl.getId(), settings);
}
// Create the URI to the .wavedev file
final org.eclipse.emf.common.util.URI uri = org.eclipse.emf.common.util.URI.createPlatformResourceURI(softPkg.getName() + "/." + softPkg.getName()
+ ".wavedev", false);
final ResourceSet set = ScaResourceFactoryUtil.createResourceSet();
final Resource res = set.createResource(uri);
// Add the WaveDevSettings to the resource and save to disk to persist the newly created WaveDevSettings
res.getContents().add(waveDev);
try {
res.save(null);
} catch (final IOException e) {
RedhawkIDEUiPlugin.logError(e.getMessage(), e);
}
return waveDev;
}
}