/******************************************************************************* * Copyright (c) 2007, 2016 Intel Corporation and others. * 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 * * Contributors: * Intel Corporation - Initial API and implementation *******************************************************************************/ package org.eclipse.cdt.managedbuilder.ui.properties; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.TreeSet; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICFileDescription; import org.eclipse.cdt.core.settings.model.ICMultiItemsHolder; import org.eclipse.cdt.core.settings.model.ICMultiResourceDescription; import org.eclipse.cdt.core.settings.model.ICResourceDescription; import org.eclipse.cdt.managedbuilder.core.IAdditionalInput; import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IFileInfo; import org.eclipse.cdt.managedbuilder.core.IInputType; import org.eclipse.cdt.managedbuilder.core.IOutputType; import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; import org.eclipse.cdt.managedbuilder.core.IResourceInfo; import org.eclipse.cdt.managedbuilder.core.ITool; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.internal.ui.Messages; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Group; /** * @noextend This class is not intended to be subclassed by clients. * @noinstantiate This class is not intended to be instantiated by clients. */ public class BuildStepsTab extends AbstractCBuildPropertyTab { private Combo combo; private Combo preCmd; private Combo preDes; private Combo postCmd; private Combo postDes; private ITool tool; private IConfiguration config; private ICResourceDescription cfgdescr; private IFileInfo rcfg; private boolean canModify = true; private static final String label1 = Messages.BuildStepsTab_0; private static final String label2 = Messages.BuildStepsTab_1; private static final String PATH_SEPERATOR = ";"; //$NON-NLS-1$ private static final String rcbsToolId = "org.eclipse.cdt.managedbuilder.ui.rcbs"; //$NON-NLS-1$ private static final String rcbsToolName = "Resource Custom Build Step"; //$NON-NLS-1$ private static final String rcbsToolInputTypeId = "org.eclipse.cdt.managedbuilder.ui.rcbs.inputtype"; //$NON-NLS-1$ private static final String rcbsToolInputTypeName = "Resource Custom Build Step Input Type"; //$NON-NLS-1$ private static final String rcbsToolOutputTypeId = "org.eclipse.cdt.managedbuilder.ui.rcbs.outputtype"; //$NON-NLS-1$ private static final String rcbsToolOutputTypeName = "Resource Custom Build Step Output Type"; //$NON-NLS-1$ private enum FIELD {PRECMD, PREANN, PSTCMD, PSTANN} private Set<String> set1 = new TreeSet<String>(); private Set<String> set2 = new TreeSet<String>(); private Set<String> set3 = new TreeSet<String>(); private Set<String> set4 = new TreeSet<String>(); private static final String[] rcbsApplicabilityRules = { Messages.ResourceCustomBuildStepBlock_label_applicability_rule_override, // ManagedBuilderMessages_getResourceString("ResourceCustomBuildStepBlock_label_applicability_rule_before"), // ManagedBuilderMessages_getResourceString("ResourceCustomBuildStepBlock_label_applicability_rule_after"), Messages.ResourceCustomBuildStepBlock_label_applicability_rule_disable, }; @Override public void createControls(Composite parent) { super.createControls(parent); usercomp.setLayout(new GridLayout(1, false)); if (page.isForProject()) createForProject(); else createForFile(); } /** * */ private void createForProject() { Group g1 = setupGroup (usercomp, Messages.BuildStepsTab_2, 1, GridData.FILL_HORIZONTAL); setupLabel(g1, label1, 1, GridData.BEGINNING); preCmd = setCombo(g1, FIELD.PRECMD, set1); preCmd.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { if (canModify && !preCmd.getText().equals(getCfg().getPrebuildStep())) getCfg().setPrebuildStep(preCmd.getText()); }}); setupLabel(g1, label2, 1, GridData.BEGINNING); preDes = setCombo(g1, FIELD.PREANN, set2); preDes.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { if (canModify && !preDes.getText().equals(getCfg().getPreannouncebuildStep())) getCfg().setPreannouncebuildStep(preDes.getText()); }}); Group g2 = setupGroup (usercomp, Messages.BuildStepsTab_3, 1, GridData.FILL_HORIZONTAL); setupLabel(g2, label1, 1, GridData.BEGINNING); postCmd = setCombo(g2, FIELD.PSTCMD, set3); postCmd.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { if (canModify && !postCmd.getText().equals(getCfg().getPostbuildStep())) getCfg().setPostbuildStep(postCmd.getText()); }}); setupLabel(g2, label2, 1, GridData.BEGINNING); postDes = setCombo(g2, FIELD.PSTANN, set4); postDes.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { if (canModify && !postDes.getText().equals(getCfg().getPostannouncebuildStep())) getCfg().setPostannouncebuildStep(postDes.getText()); }}); } /** * */ private void createForFile() { Group g1 = setupGroup (usercomp, Messages.BuildStepsTab_4, 1, GridData.FILL_HORIZONTAL); setupLabel(g1, Messages.ResourceCustomBuildStepBlock_label_applicability, 1, GridData.BEGINNING); combo = new Combo(g1, SWT.READ_ONLY | SWT.DROP_DOWN | SWT.BORDER); combo.setItems(rcbsApplicabilityRules); combo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { rcfg.setRcbsApplicability(sel2app(combo.getSelectionIndex())); }}); setupLabel(g1, Messages.BuildStepsTab_5, 1, GridData.BEGINNING); preCmd = setCombo(g1, FIELD.PRECMD, set1); preCmd.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { if (canModify && tool != null) { IInputType[] ein = tool.getInputTypes(); if (ein != null && ein.length > 0) { IAdditionalInput[] add = ein[0].getAdditionalInputs(); if (add != null && add.length > 0) { add[0].setPaths(preCmd.getText()); } } } }}); setupLabel(g1, Messages.BuildStepsTab_6, 1, GridData.BEGINNING); preDes = setCombo(g1, FIELD.PREANN, set2); preDes.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { if (canModify && tool != null) { IOutputType[] out = tool.getOutputTypes(); if (valid(out)) out[0].setOutputNames(preDes.getText()); } }}); setupLabel(g1, label1, 1, GridData.BEGINNING); postCmd = setCombo(g1, FIELD.PSTCMD, set3); postCmd.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { if (canModify && tool != null) tool.setToolCommand(postCmd.getText()); }}); setupLabel(g1, label2, 1, GridData.BEGINNING); postDes = setCombo(g1, FIELD.PSTANN, set4); postDes.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { if (canModify && tool != null) tool.setAnnouncement(postDes.getText()); }}); } @Override public void updateData(ICResourceDescription cfgd) { if (cfgd == null) return; config = getCfg(cfgd.getConfiguration()); cfgdescr = cfgd; update(); } private void update() { canModify = false; // avoid changing updateCombo(preCmd); updateCombo(preDes); updateCombo(postCmd); updateCombo(postDes); if (page.isForProject()) { preCmd.setText(config.getPrebuildStep()); preDes.setText(config.getPreannouncebuildStep()); postCmd.setText(config.getPostbuildStep()); postDes.setText(config.getPostannouncebuildStep()); } else { rcfg = (IFileInfo)getResCfg(cfgdescr); combo.select(app2sel(rcfg.getRcbsApplicability())); tool = getRcbsTool(rcfg); if(tool != null){ preCmd.setText(getInputTypes(tool)); preDes.setText(getOutputNames(tool)); postCmd.setText(tool.getToolCommand()); postDes.setText(tool.getAnnouncement()); } else { preCmd.setText(EMPTY_STR); preDes.setText(EMPTY_STR); postCmd.setText(EMPTY_STR); postDes.setText(EMPTY_STR); } } canModify = true; } private String getInputTypes(ITool t) { String s = EMPTY_STR; IInputType[] tmp = t.getInputTypes(); if (tmp != null && tmp.length > 0) { IAdditionalInput[] add = tmp[0].getAdditionalInputs(); if (add != null && add.length > 0) s = createList(add[0].getPaths()); } return s; } private String getOutputNames(ITool t) { String s = EMPTY_STR; IOutputType[] tmp2 = t.getOutputTypes(); if (tmp2 != null && tmp2.length > 0) s = createList(tmp2[0].getOutputNames()); return s; } private ITool getRcbsTool(IFileInfo rcConfig){ ITool rcbsTools[] = getRcbsTools(rcConfig); ITool rcbsTool = null; if(rcbsTools != null) rcbsTool = rcbsTools[0]; else { rcbsTool = rcConfig.createTool(null,rcbsToolId + "." + ManagedBuildManager.getRandomNumber(),rcbsToolName,false); //$NON-NLS-1$ rcbsTool.setCustomBuildStep(true); IInputType rcbsToolInputType = rcbsTool.createInputType(null,rcbsToolInputTypeId + "." + ManagedBuildManager.getRandomNumber(),rcbsToolInputTypeName,false); //$NON-NLS-1$ IAdditionalInput rcbsToolInputTypeAdditionalInput = rcbsToolInputType.createAdditionalInput(""); //$NON-NLS-1$ rcbsToolInputTypeAdditionalInput.setKind(IAdditionalInput.KIND_ADDITIONAL_INPUT_DEPENDENCY); rcbsTool.createOutputType(null,rcbsToolOutputTypeId + "." + ManagedBuildManager.getRandomNumber(),rcbsToolOutputTypeName,false); //$NON-NLS-1$ } return rcbsTool; } private ITool[] getRcbsTools(IResourceInfo rcConfig){ List<ITool> list = new ArrayList<ITool>(); ITool tools[] = rcConfig.getTools(); for (int i = 0; i < tools.length; i++) { ITool tool = tools[i]; if (tool.getCustomBuildStep() && !tool.isExtensionElement()) { list.add(tool); } } if(list.size() != 0) { return list.toArray(new ITool[list.size()]); } return null; } private String createList(String[] items) { if(items == null) return ""; //$NON-NLS-1$ StringBuilder path = new StringBuilder(EMPTY_STR); for (int i = 0; i < items.length; i++) { path.append(items[i]); if (i < (items.length - 1)) { path.append(PATH_SEPERATOR); } } return path.toString(); } @Override public void performApply(ICResourceDescription src, ICResourceDescription dst) { if (page.isForProject()) { IConfiguration cfg1 = getCfg(src.getConfiguration()); IConfiguration cfg2 = getCfg(dst.getConfiguration()); cfg2.setPrebuildStep(cfg1.getPrebuildStep()); cfg2.setPreannouncebuildStep(cfg1.getPreannouncebuildStep()); cfg2.setPostbuildStep(cfg1.getPostbuildStep()); cfg2.setPostannouncebuildStep(cfg1.getPostannouncebuildStep()); } else { if (page.isMultiCfg()) { ICResourceDescription[] ris1 = (ICResourceDescription[])((ICMultiResourceDescription)src).getItems(); ICResourceDescription[] ris2 = (ICResourceDescription[])((ICMultiResourceDescription)dst).getItems(); for (int i=0; i<ris1.length; i++) applyToFile(ris1[i], ris2[i]); } else applyToFile(src, dst); } } private void applyToFile(ICResourceDescription src, ICResourceDescription dst) { IFileInfo rcfg1 = (IFileInfo)getResCfg(src); IFileInfo rcfg2 = (IFileInfo)getResCfg(dst); rcfg2.setRcbsApplicability(rcfg1.getRcbsApplicability()); ITool tool1 = getRcbsTool(rcfg1); ITool tool2 = getRcbsTool(rcfg2); IInputType[] ein1 = tool1.getInputTypes(); IInputType[] ein2 = tool2.getInputTypes(); if (valid(ein1) && valid(ein2)) { IAdditionalInput[] add1 = ein1[0].getAdditionalInputs(); IAdditionalInput[] add2 = ein2[0].getAdditionalInputs(); if (valid(add1) && valid(add2)) { // if (add1 != null && add2 != null && add1.length > 0 && add2.length > 0) { add2[0].setPaths(createList(add1[0].getPaths())); } } IOutputType[] tmp1 = tool1.getOutputTypes(); IOutputType[] tmp2 = tool2.getOutputTypes(); // if (tmp1 != null && tmp2 != null && tmp1.length > 0 && tmp2.length > 0) { if (valid(tmp1) && valid(tmp2)) { tmp2[0].setOutputNames(createList(tmp1[0].getOutputNames())); } tool2.setToolCommand(tool1.getToolCommand()); tool2.setAnnouncement(tool1.getAnnouncement()); } private int sel2app(int index){ String sel = combo.getItem(index); if(Messages.ResourceCustomBuildStepBlock_label_applicability_rule_override.equals(sel)){ return IResourceConfiguration.KIND_APPLY_RCBS_TOOL_AS_OVERRIDE; } else if(Messages.ResourceCustomBuildStepBlock_label_applicability_rule_after.equals(sel)){ return IResourceConfiguration.KIND_APPLY_RCBS_TOOL_AFTER; } else if(Messages.ResourceCustomBuildStepBlock_label_applicability_rule_before.equals(sel)){ return IResourceConfiguration.KIND_APPLY_RCBS_TOOL_BEFORE; } return IResourceConfiguration.KIND_DISABLE_RCBS_TOOL; } private boolean valid(Object[] arr) { return (arr != null && arr.length > 0); } private int app2sel(int val){ switch(val){ case IResourceConfiguration.KIND_APPLY_RCBS_TOOL_AFTER: return combo.indexOf(Messages.ResourceCustomBuildStepBlock_label_applicability_rule_after); case IResourceConfiguration.KIND_APPLY_RCBS_TOOL_BEFORE: return combo.indexOf(Messages.ResourceCustomBuildStepBlock_label_applicability_rule_before); case IResourceConfiguration.KIND_DISABLE_RCBS_TOOL: return combo.indexOf(Messages.ResourceCustomBuildStepBlock_label_applicability_rule_disable); case IResourceConfiguration.KIND_APPLY_RCBS_TOOL_AS_OVERRIDE: default: return combo.indexOf(Messages.ResourceCustomBuildStepBlock_label_applicability_rule_override); } } // This page can be displayed for managed project only @Override public boolean canBeVisible() { if (page.isForProject() || page.isForFile()) { if (page.isMultiCfg()) { ICMultiItemsHolder mih = (ICMultiItemsHolder)getCfg(); IConfiguration[] cfs = (IConfiguration[])mih.getItems(); for (int i=0; i<cfs.length; i++) { if (cfs[i].getBuilder().isManagedBuildOn()) return true; } return false; } else return getCfg().getBuilder().isManagedBuildOn(); } else return false; } @Override protected void performDefaults() { if (page.isForProject()) { config.setPrebuildStep(null); config.setPreannouncebuildStep(null); config.setPostbuildStep(null); config.setPostannouncebuildStep(null); } else { rcfg.setRcbsApplicability(IResourceConfiguration.KIND_DISABLE_RCBS_TOOL); ITool tool = getRcbsTool(rcfg); IInputType[] ein = tool.getInputTypes(); if (valid(ein)) { IAdditionalInput[] add = ein[0].getAdditionalInputs(); if (valid(add)) add[0].setPaths(null); } IOutputType[] tmp = tool.getOutputTypes(); if (valid(tmp)) tmp[0].setOutputNames(null); tool.setToolCommand(null); tool.setAnnouncement(null); } update(); } @Override protected void updateButtons() {} // Do nothing. No buttons to update. private Combo setCombo(Composite c, FIELD field, Set<String> set) { Combo combo = new Combo(c, SWT.BORDER); setupControl(combo, 1, GridData.FILL_HORIZONTAL); combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); combo.setData(ENUM, field); combo.setData(SSET, set); updateCombo(combo); return combo; } @SuppressWarnings("unchecked") private void updateCombo(Combo combo) { FIELD field = (FIELD)combo.getData(ENUM); Set<String> set = (Set<String>)combo.getData(SSET); if (field == null || set == null) return; combo.removeAll(); boolean prj = page.isForProject(); if (prj || tool != null) { for (ICConfigurationDescription cf : page.getCfgsEditable()) { IConfiguration c = null; ITool t = null; if (prj) { c = getCfg(cf); } else { ICResourceDescription r = cf.getResourceDescription(cfgdescr.getPath(), true); if (r != null && r instanceof ICFileDescription) t = getRcbsTool((IFileInfo)getResCfg(r)); if (t == null) continue; // there's no specific resconfig for this configuration } String s = null; switch (field) { case PRECMD: s = prj ? c.getPrebuildStep() : getInputTypes(t); break; case PREANN: s = prj ? c.getPreannouncebuildStep() : getOutputNames(t); break; case PSTCMD: s = prj ? c.getPostbuildStep() : t.getToolCommand(); break; case PSTANN: s = prj ? c.getPostannouncebuildStep() : t.getAnnouncement(); break; } if (s != null && s.trim().length() > 0) set.add(s.trim()); } } if (set.size() > 0) combo.setItems(set.toArray(new String[set.size()])); } }