package com.arm.cmsis.pack.project.ui.handlers;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.compare.BufferedContent;
import org.eclipse.compare.CompareConfiguration;
import org.eclipse.compare.CompareEditorInput;
import org.eclipse.compare.CompareUI;
import org.eclipse.compare.IEditableContent;
import org.eclipse.compare.ITypedElement;
import org.eclipse.compare.structuremergeviewer.DiffNode;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFileState;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.ISelectionService;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.commands.IElementUpdater;
import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.ui.menus.UIElement;
import com.arm.cmsis.pack.data.ICpFile;
import com.arm.cmsis.pack.enums.EFileCategory;
import com.arm.cmsis.pack.enums.EFileRole;
import com.arm.cmsis.pack.info.ICpFileInfo;
import com.arm.cmsis.pack.project.CpProjectPlugIn;
import com.arm.cmsis.pack.project.IRteProject;
import com.arm.cmsis.pack.project.Messages;
import com.arm.cmsis.pack.project.RteProjectStorage;
import com.arm.cmsis.pack.project.utils.ProjectUtils;
import com.arm.cmsis.pack.utils.Utils;
public class MergeConfigFileHandler extends AbstractHandler implements IElementUpdater {
class CompareConfigFileInput extends CompareEditorInput {
private DiffNode fRoot;
private CompareItem fLeft;
private CompareItem fRight;
private class CompareItem extends BufferedContent implements IEditableContent, ITypedElement {
protected IStorage fContent;
public CompareItem(IStorage storage) {
fContent = storage;
}
@Override
public boolean isEditable() {
return true;
}
@Override
public ITypedElement replace(ITypedElement dest, ITypedElement src) {
return dest;
}
@Override
public String getName() {
return Utils.extractBaseFileName(fContent.getName());
}
@Override
public Image getImage() {
return null;
}
@Override
public String getType() {
return Utils.extractFileExtension(fContent.getName());
}
@Override
protected InputStream createStream() throws CoreException {
return fContent.getContents();
}
}
/**
* @param configuration
*/
public CompareConfigFileInput(IFile currentFile, IFileState previousFile, String currentVersion, String previousVersion) {
super(new CompareConfiguration());
setTitle("Compare " + currentFile.getLocation().toOSString() + " previous and current revision"); //$NON-NLS-1$ //$NON-NLS-2$
getCompareConfiguration().setLeftEditable(true);
getCompareConfiguration().setRightEditable(false);
getCompareConfiguration().setLeftLabel("Local: " + currentFile.getName() + " (" + currentVersion + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
getCompareConfiguration().setRightLabel("Previous version (" + previousVersion + ")"); //$NON-NLS-1$ //$NON-NLS-2$
fLeft = new CompareItem(currentFile);
fRight = new CompareItem(previousFile);
}
@Override
protected Object prepareInput(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
fRoot = new DiffNode(fLeft, fRight);
return fRoot;
}
@Override
public void saveChanges(IProgressMonitor pm) throws CoreException {
super.saveChanges(pm);
IStorage resource = fLeft.fContent;
if (resource instanceof IFile) {
byte[] bytes = fLeft.getContent();
ByteArrayInputStream is = new ByteArrayInputStream(bytes);
IFile file = (IFile) resource;
try {
if (file.exists()) {
file.setContents(is, true, true, pm);
} else {
file.create(is, true, pm);
}
} finally {
if (is != null) {
try {
is.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
}
}
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
ISelection selection = HandlerUtil.getCurrentSelection(event);
if (!(selection instanceof IStructuredSelection)) {
return null;
}
Object obj = ((IStructuredSelection) selection).getFirstElement();
IFile file = ProjectUtils.getRteFileResource(obj);
String dstFile = file.getProjectRelativePath().toString();
ICpFileInfo fi = ProjectUtils.getCpFileInfo(file);
ICpFile f = fi.getFile();
String srcFile = f.getAbsolutePath(f.getName());
EFileRole role = fi.getRole();
if (role == EFileRole.CONFIG || role == EFileRole.COPY) {
int index = -1;
EFileCategory cat = fi.getCategory();
if (cat.isHeader() || cat.isSource()) {
String baseSrc = Utils.extractBaseFileName(srcFile);
String baseDst = Utils.extractBaseFileName(dstFile);
int len = baseSrc.length() + 1;
if (baseDst.length() > len) {
String instance = baseDst.substring(len);
try {
index = Integer.decode(instance);
} catch (NumberFormatException e) {
// do nothing, use -1
}
}
}
try {
int bCopied = ProjectUtils.copyFile(file.getProject(), srcFile, dstFile, index, null, true);
if (bCopied == 1) {
String previousVersion = fi.getVersion();
// do the version update and save it in the .cproject file
fi.setVersion(f.getVersion());
IRteProject rteProject = CpProjectPlugIn.getRteProjectManager().getRteProject(file.getProject());
RteProjectStorage projectStorage = rteProject.getProjectStorage();
projectStorage.setConfigFileVersion(dstFile, f.getVersion());
projectStorage.save(CoreModel.getDefault().getProjectDescription(file.getProject()));
rteProject.save();
if (role == EFileRole.CONFIG) {
IFileState fileState = file.getHistory(null)[0];
CompareConfigFileInput compareInput = new CompareConfigFileInput(file, fileState,
fi.getVersion(), previousVersion);
CompareUI.openCompareEditorOnPage(compareInput,
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage());
}
}
} catch (CoreException e) {
e.printStackTrace();
}
}
return null;
}
@Override
public void updateElement(UIElement element, @SuppressWarnings("rawtypes") Map parameters) {
ISelectionService selectionService = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
ISelection selection = selectionService.getSelection("org.eclipse.ui.navigator.ProjectExplorer"); //$NON-NLS-1$
if (selection instanceof IStructuredSelection) {
Object obj = ((IStructuredSelection) selection).getFirstElement();
IFile file = ProjectUtils.getRteFileResource(obj);
ICpFileInfo fi = ProjectUtils.getCpFileInfo(file);
if (fi == null || fi.getFile() == null) {
return;
}
int versionDiff = fi.getVersionDiff();
String versionText = " (" + fi.getVersion() + " -> " + fi.getFile().getVersion() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
if (versionDiff < 0 || versionDiff > 2) {
element.setText(Messages.MergeConfigFileHandler_Merge + file.getName() + versionText);
}
}
}
}