/******************************************************************************* * Copyright (c) 2006-2013, Cloudsmith Inc. * The code, documentation and other materials contained herein have been * licensed under the Eclipse Public License - v 1.0 by the copyright holder * listed above, as the Initial Contributor under such license. The text of * such license is available at www.eclipse.org. ******************************************************************************/ package org.eclipse.buckminster.ui.editor.cspec; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.buckminster.core.CorePlugin; import org.eclipse.buckminster.core.common.model.Documentation; import org.eclipse.buckminster.core.cspec.builder.ActionArtifactBuilder; import org.eclipse.buckminster.core.cspec.builder.ActionBuilder; import org.eclipse.buckminster.core.cspec.builder.ArtifactBuilder; import org.eclipse.buckminster.core.cspec.builder.AttributeBuilder; import org.eclipse.buckminster.core.cspec.builder.CSpecBuilder; import org.eclipse.buckminster.core.cspec.builder.ComponentRequestBuilder; import org.eclipse.buckminster.core.cspec.builder.GeneratorBuilder; import org.eclipse.buckminster.core.cspec.builder.GroupBuilder; import org.eclipse.buckminster.core.cspec.model.AttributeAlreadyDefinedException; import org.eclipse.buckminster.core.cspec.model.CSpec; import org.eclipse.buckminster.core.cspec.model.GeneratorAlreadyDefinedException; import org.eclipse.buckminster.core.ctype.AbstractComponentType; import org.eclipse.buckminster.core.helpers.TextUtils; import org.eclipse.buckminster.core.parser.IParser; import org.eclipse.buckminster.core.version.VersionHelper; import org.eclipse.buckminster.core.version.VersionType; import org.eclipse.buckminster.runtime.BuckminsterException; import org.eclipse.buckminster.runtime.IOUtils; import org.eclipse.buckminster.sax.Utils; import org.eclipse.buckminster.ui.Messages; import org.eclipse.buckminster.ui.SaveRunnable; import org.eclipse.buckminster.ui.UiUtils; import org.eclipse.buckminster.ui.editor.ArtifactType; import org.eclipse.buckminster.ui.editor.EditorUtils; import org.eclipse.buckminster.ui.editor.IDerivedEditorInput; import org.eclipse.buckminster.ui.general.editor.ITableModifyListener; import org.eclipse.buckminster.ui.general.editor.TableModifyEvent; import org.eclipse.buckminster.ui.general.editor.simple.SimpleTableEditor; import org.eclipse.buckminster.ui.general.editor.structured.FieldModifyEvent; import org.eclipse.buckminster.ui.general.editor.structured.IActivator; import org.eclipse.buckminster.ui.general.editor.structured.IFieldModifyListener; import org.eclipse.buckminster.ui.general.editor.structured.OnePageTableEditor; import org.eclipse.buckminster.ui.internal.CSpecEditorInput; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.equinox.p2.metadata.Version; import org.eclipse.equinox.p2.metadata.VersionRange; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.window.Window; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CTabFolder; import org.eclipse.swt.custom.CTabItem; 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.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorMatchingStrategy; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorReference; import org.eclipse.ui.IEditorSite; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.IPathEditorInput; import org.eclipse.ui.IURIEditorInput; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.PartInitException; import org.eclipse.ui.dialogs.SaveAsDialog; import org.eclipse.ui.editors.text.ILocationProvider; import org.eclipse.ui.part.EditorPart; /** * @author Karel Brezina * */ public class CSpecEditor extends EditorPart implements IEditorMatchingStrategy { // don't need generics here - need just to setDirty class CompoundModifyListener<T> implements ModifyListener, ITableModifyListener<T>, IFieldModifyListener { @Override public void modifyField(FieldModifyEvent e) { setDirty(true); } @Override public void modifyTable(TableModifyEvent<T> e) { setDirty(true); } @Override public void modifyText(ModifyEvent e) { setDirty(true); } } enum CSpecEditorTab { MAIN(0), ACTIONS(1), ARTIFACTS(2), GROUPS(3), ATTRIBUTES(4), DEPENDENCIES(5), GENERATORS(6), DOCUMENTATION(6), XML(8); private int seqNum; CSpecEditorTab(int seqNum) { this.seqNum = seqNum; } public int getSeqNum() { return seqNum; } } private static final String SAVEABLE_CSPEC_NAME = "buckminster.cspec"; //$NON-NLS-1$ private CSpecBuilder cspec; private List<ActionBuilder> actionBuilders = new ArrayList<ActionBuilder>(); private Map<ActionBuilder, List<ActionArtifactBuilder>> actionArtifactBuilders = new HashMap<ActionBuilder, List<ActionArtifactBuilder>>(); private List<ArtifactBuilder> artifactBuilders = new ArrayList<ArtifactBuilder>(); private List<GroupBuilder> groupBuilders = new ArrayList<GroupBuilder>(); private List<ComponentRequestBuilder> dependencyBuilders = new ArrayList<ComponentRequestBuilder>(); private List<GeneratorBuilder> generatorBuilders = new ArrayList<GeneratorBuilder>(); @SuppressWarnings("rawtypes") private CompoundModifyListener compoundModifyListener; private boolean hasChanges = false; private boolean mute = false; private boolean needsRefresh = false; private boolean readOnly = true; private CTabFolder tabFolder; private CTabItem mainTab; private CTabItem actionsTab; private CTabItem artifactsTab; private CTabItem groupsTab; private CTabItem attributesTab; private CTabItem dependenciesTab; private CTabItem generatorsTab; private CTabItem documentationTab; private CTabItem xmlTab; private Text componentName; private Combo componentType; private Text versionString; private Combo versionType; private ActionsTable actionsTable; private OnePageTableEditor<ActionBuilder> actionsEditor; private OnePageTableEditor<ArtifactBuilder> artifactsEditor; private OnePageTableEditor<GroupBuilder> groupsEditor; private AllAttributesView attributesView; private SimpleTableEditor<ComponentRequestBuilder> dependenciesEditor; private SimpleTableEditor<GeneratorBuilder> generatorsEditor; private Text shortDesc; private Text documentation; private Text xml; private Button externalSaveAsButton; @Override public void createPartControl(Composite parent) { Composite topComposite = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(1, true); layout.marginHeight = layout.marginWidth = 0; topComposite.setLayout(layout); tabFolder = new CTabFolder(topComposite, SWT.BOTTOM); tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); mainTab = new CTabItem(tabFolder, SWT.NONE); mainTab.setText(Messages.main); mainTab.setControl(getMainTabControl(tabFolder)); mainTab.setData(CSpecEditorTab.MAIN); actionsTab = new CTabItem(tabFolder, SWT.NONE); actionsTab.setText(Messages.actions); actionsTab.setControl(getActionsTabControl(tabFolder)); actionsTab.setData(CSpecEditorTab.ACTIONS); artifactsTab = new CTabItem(tabFolder, SWT.NONE); artifactsTab.setText(Messages.artifacts); artifactsTab.setControl(getArtifactsTabControl(tabFolder)); artifactsTab.setData(CSpecEditorTab.ARTIFACTS); groupsTab = new CTabItem(tabFolder, SWT.NONE); groupsTab.setText(Messages.groups); groupsTab.setControl(getGroupsTabControl(tabFolder)); groupsTab.setData(CSpecEditorTab.GROUPS); attributesTab = new CTabItem(tabFolder, SWT.NONE); attributesTab.setText(Messages.all_attributes); attributesTab.setControl(getAttributesTabControl(tabFolder)); attributesTab.setData(CSpecEditorTab.ATTRIBUTES); dependenciesTab = new CTabItem(tabFolder, SWT.NONE); dependenciesTab.setText(Messages.dependencies); dependenciesTab.setControl(getDependenciesTabControl(tabFolder)); dependenciesTab.setData(CSpecEditorTab.DEPENDENCIES); generatorsTab = new CTabItem(tabFolder, SWT.NONE); generatorsTab.setText(Messages.generators); generatorsTab.setControl(getGeneratorsTabControl(tabFolder)); generatorsTab.setData(CSpecEditorTab.GENERATORS); documentationTab = new CTabItem(tabFolder, SWT.NONE); documentationTab.setText(Messages.documentation); documentationTab.setControl(getDocumentationTabControl(tabFolder)); documentationTab.setData(CSpecEditorTab.DOCUMENTATION); xmlTab = new CTabItem(tabFolder, SWT.NONE); xmlTab.setText(Messages.xml_content); xmlTab.setControl(getXMLTabControl(tabFolder)); xmlTab.setData(CSpecEditorTab.XML); tabFolder.addSelectionListener(new SelectionAdapter() { private final IActivator ACTIONS_ACTIVATOR = new IActivator() { @Override public void activate() { switchTab(CSpecEditorTab.ACTIONS); } }; private final IActivator ARTIFACTS_ACTIVATOR = new IActivator() { @Override public void activate() { switchTab(CSpecEditorTab.ARTIFACTS); } }; private final IActivator GROUPS_ACTIVATOR = new IActivator() { @Override public void activate() { switchTab(CSpecEditorTab.GROUPS); } }; private CTabItem lastTab = mainTab; @Override public void widgetSelected(SelectionEvent e) { // save row if (lastTab != e.item) { if (lastTab == actionsTab) if (!actionsEditor.save(ACTIONS_ACTIVATOR)) return; if (lastTab == artifactsTab) if (!artifactsEditor.save(ARTIFACTS_ACTIVATOR)) return; if (lastTab == groupsTab) if (!groupsEditor.save(GROUPS_ACTIVATOR)) return; } if (mainTab == e.item) { componentName.setFocus(); } else if (actionsTab == e.item) { actionsEditor.setFocus(); } else if (artifactsTab == e.item) { artifactsEditor.setFocus(); } else if (groupsTab == e.item) { groupsEditor.setFocus(); } else if (attributesTab == e.item) { attributesView.setFocus(); } else if (dependenciesTab == e.item) { dependenciesEditor.setFocus(); } else if (generatorsTab == e.item) { generatorsEditor.setFocus(); } else if (documentationTab == e.item) { shortDesc.setFocus(); } else if (xmlTab == e.item) { if (!commitChanges()) MessageDialog.openWarning(getSite().getShell(), null, Messages.xml_content_was_not_updated_due_to_errors); else xml.setText(getCSpecXML()); } lastTab = (CTabItem) e.item; } }); createActionButtons(topComposite); } public void doExternalSaveAs() { if (!commitChanges()) return; FileDialog dlg = new FileDialog(getSite().getShell(), SWT.SAVE); dlg.setFilterExtensions(new String[] { "*.cspec" }); //$NON-NLS-1$ final String location = dlg.open(); if (location == null) return; saveToPath(new Path(location)); } @Override public void doSave(IProgressMonitor monitor) { if (!commitChanges()) return; IEditorInput input = getEditorInput(); if (input == null) return; IPath path = (input instanceof ILocationProvider) ? ((ILocationProvider) input).getPath(input) : ((IPathEditorInput) input).getPath(); saveToPath(path); } @Override public void doSaveAs() { if (!commitChanges()) return; IEditorInput input = getEditorInput(); if (input == null) return; SaveAsDialog dialog = new SaveAsDialog(getSite().getShell()); IFile original = (input instanceof IFileEditorInput) ? ((IFileEditorInput) input).getFile() : null; if (original != null) dialog.setOriginalFile(original); if (dialog.open() == Window.CANCEL) return; IPath filePath = dialog.getResult(); if (filePath == null) return; IWorkspace workspace = ResourcesPlugin.getWorkspace(); IFile file = workspace.getRoot().getFile(filePath); saveToPath(file.getLocation()); } @Override public void init(IEditorSite site, IEditorInput input) throws PartInitException { if (!(input instanceof ILocationProvider || input instanceof IPathEditorInput || input instanceof IURIEditorInput || input instanceof CSpecEditorInput)) throw new PartInitException(Messages.invalid_input); setSite(site); if (input instanceof IURIEditorInput) { try { input = EditorUtils.getExternalFileEditorInput((IURIEditorInput) input, ArtifactType.CSPEC); } catch (Exception e) { throw new PartInitException(Messages.unable_to_open_editor, e); } } InputStream stream = null; try { cspec = new CSpecBuilder(); if (input instanceof CSpecEditorInput) { readOnly = true; cspec.initFrom(((CSpecEditorInput) input).getCSpec()); } else { IPath path = (input instanceof ILocationProvider) ? ((ILocationProvider) input).getPath(input) : ((IPathEditorInput) input).getPath(); readOnly = (!SAVEABLE_CSPEC_NAME.equalsIgnoreCase(path.lastSegment())); File file = path.toFile(); if (file.length() != 0) { String systemId = file.toString(); stream = new FileInputStream(file); IParser<CSpec> parser = CorePlugin.getDefault().getParserFactory().getCSpecParser(true); cspec.initFrom(parser.parse(systemId, stream)); } } needsRefresh = true; if (componentName != null) { refreshValues(); } setInputWithNotify(input); setPartName(input.getName() + (readOnly ? Messages.read_only_in_paranthesis : "")); //$NON-NLS-1$ } catch (Exception e) { throw new PartInitException(BuckminsterException.wrap(e).getMessage()); } finally { IOUtils.close(stream); } compoundModifyListener = new CompoundModifyListener<Object>(); } @Override public boolean isDirty() { return hasChanges; } @Override public boolean isSaveAsAllowed() { return !readOnly; } @Override public boolean matches(IEditorReference editorRef, IEditorInput input) { IEditorPart part = (IEditorPart) editorRef.getPart(false); if (part != null) { IEditorInput editorInput = part.getEditorInput(); if (editorInput != null) { if (editorInput.equals(input)) return true; if (editorInput instanceof IDerivedEditorInput) { IEditorInput originalEditorInput = ((IDerivedEditorInput) editorInput).getOriginalInput(); if (originalEditorInput.equals(input)) return true; } } } return false; } public void setEnabled(boolean enabled) { componentName.setEnabled(enabled); componentType.setEnabled(enabled); versionString.setEnabled(enabled); versionType.setEnabled(enabled); actionsEditor.setEnabled(enabled); artifactsEditor.setEnabled(enabled); groupsEditor.setEnabled(enabled); dependenciesEditor.setEnabled(enabled); generatorsEditor.setEnabled(enabled); shortDesc.setEnabled(enabled); documentation.setEnabled(enabled); } @Override public void setFocus() { tabFolder.setFocus(); if (needsRefresh) { refreshValues(); } } Map<ActionBuilder, List<ActionArtifactBuilder>> getActionArtifactBuilders() { return actionArtifactBuilders; } List<ActionBuilder> getActionBuilders() { return actionBuilders; } OnePageTableEditor<ActionBuilder> getActionsEditor() { return actionsEditor; } ActionsTable getActionsTable() { return actionsTable; } List<ArtifactBuilder> getArtifactBuilders() { return artifactBuilders; } OnePageTableEditor<ArtifactBuilder> getArtifactsEditor() { return artifactsEditor; } String[] getAttributeNames(String excludeName) { List<String> nameList = new ArrayList<String>(); for (ActionBuilder builder : actionBuilders) { if (builder.getName() != null) { nameList.add(builder.getName()); } } for (List<ActionArtifactBuilder> list : actionArtifactBuilders.values()) for (ActionArtifactBuilder builder : list) nameList.add(builder.getName()); for (ArtifactBuilder builder : artifactBuilders) { if (builder.getName() != null) { nameList.add(builder.getName()); } } for (GroupBuilder builder : groupBuilders) { if (builder.getName() != null) { nameList.add(builder.getName()); } } if (excludeName != null) { nameList.remove(excludeName); } String[] array = nameList.toArray(new String[0]); Arrays.sort(array, new Comparator<String>() { @Override public int compare(String o1, String o2) { return o1.compareTo(o2); } }); return array; } String[] getComponentNames() { List<String> list = new ArrayList<String>(); for (ComponentRequestBuilder builder : dependencyBuilders) { if (builder.getName() != null) { list.add(builder.getName()); } } String[] array = list.toArray(new String[0]); Arrays.sort(array, new Comparator<String>() { @Override public int compare(String o1, String o2) { return o1.compareTo(o2); } }); return array; } ComponentRequestBuilder getDependencyBuilder(String cname, String ctype, String rangeStr) { ctype = TextUtils.notEmptyString(cname); if (cname == null) return null; ctype = TextUtils.notEmptyString(ctype); rangeStr = TextUtils.notEmptyString(rangeStr); VersionRange range = rangeStr == null ? null : new VersionRange(rangeStr); for (ComponentRequestBuilder builder : dependencyBuilders) { if (!cname.equals(builder.getName())) continue; if (ctype != null && !ctype.equals(builder.getComponentTypeID())) continue; if (range != null && !range.equals(builder.getVersionRange())) continue; return builder; } return null; } List<ComponentRequestBuilder> getDependencyBuilders() { return dependencyBuilders; } List<GeneratorBuilder> getGeneratorBuilders() { return generatorBuilders; } List<GroupBuilder> getGroupBuilders() { return groupBuilders; } OnePageTableEditor<GroupBuilder> getGroupsEditor() { return groupsEditor; } void switchTab(CSpecEditorTab tab) { tabFolder.setSelection(tab.getSeqNum()); } private void addToActionArtifactBuilderMap(ActionArtifactBuilder actionArtifactbuilder) { if (actionArtifactbuilder.getActionName() == null) return; ActionBuilder actionBuilder = findActionBuilder(actionArtifactbuilder.getActionName()); if (actionBuilder != null) { List<ActionArtifactBuilder> list = actionArtifactBuilders.get(actionBuilder); if (list == null) { list = new ArrayList<ActionArtifactBuilder>(); actionArtifactBuilders.put(actionBuilder, list); } list.add(actionArtifactbuilder); } } private boolean commitChanges() { if (actionsEditor.isVisible()) if (!actionsEditor.save()) return false; if (artifactsEditor.isVisible()) if (!artifactsEditor.save()) return false; if (groupsEditor.isVisible()) if (!groupsEditor.save()) return false; String name = UiUtils.trimmedValue(componentName); if (name == null) { MessageDialog.openError(getSite().getShell(), null, Messages.the_component_must_have_a_name); return false; } cspec.setName(name); String cType = componentType.getItem(componentType.getSelectionIndex()); if (cType.length() == 0) cType = null; cspec.setComponentTypeID(cType); try { cspec.setVersion(VersionHelper.createVersion(versionType.getItem(versionType.getSelectionIndex()), UiUtils.trimmedValue(versionString))); } catch (CoreException e) { MessageDialog.openError(getSite().getShell(), null, e.getMessage()); return false; } try { Map<String, AttributeBuilder> attributesMap = cspec.getAttributes(); if (attributesMap != null) { attributesMap.clear(); } for (ActionBuilder action : actionBuilders) { cspec.addAttribute(action); } for (List<ActionArtifactBuilder> list : actionArtifactBuilders.values()) for (ActionArtifactBuilder item : list) cspec.addAttribute(item); for (ArtifactBuilder artifact : artifactBuilders) { cspec.addAttribute(artifact); } for (GroupBuilder group : groupBuilders) { cspec.addAttribute(group); } } catch (AttributeAlreadyDefinedException e) { MessageDialog.openError(getSite().getShell(), null, e.getMessage()); return false; } try { List<ComponentRequestBuilder> dependencyList = cspec.getDependencyBuilders(); if (dependencyList != null) { dependencyList.clear(); } for (ComponentRequestBuilder dependency : dependencyBuilders) { cspec.addDependency(dependency); } } catch (CoreException e) { MessageDialog.openError(getSite().getShell(), null, e.getMessage()); return false; } try { Collection<GeneratorBuilder> generators = cspec.getGeneratorList(); if (generators.size() > 0) { generators.clear(); } for (GeneratorBuilder generator : generatorBuilders) { cspec.addGenerator(generator); } } catch (GeneratorAlreadyDefinedException e) { MessageDialog.openError(getSite().getShell(), null, e.getMessage()); return false; } String doc = UiUtils.trimmedValue(shortDesc); cspec.setShortDesc(doc); doc = UiUtils.trimmedValue(documentation); try { cspec.setDocumentation(doc == null ? null : Documentation.parse(doc)); } catch (CoreException e) { MessageDialog.openError(getSite().getShell(), null, e.getMessage()); return false; } try { cspec.createCSpec().verifyConsistency(); } catch (CoreException e) { MessageDialog.openError(getSite().getShell(), null, e.getMessage()); return false; } return true; } private void createActionButtons(Composite parent) { Composite allButtonsBox = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(2, false); // layout.marginHeight = layout.marginWidth = 0; allButtonsBox.setLayout(layout); allButtonsBox.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); Composite pressButtonsBox = new Composite(allButtonsBox, SWT.NONE); layout = new GridLayout(1, true); layout.marginHeight = layout.marginWidth = 0; pressButtonsBox.setLayout(layout); pressButtonsBox.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false)); externalSaveAsButton = UiUtils.createPushButton(pressButtonsBox, Messages.external_save_as, new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { doExternalSaveAs(); } }); externalSaveAsButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); } private ActionBuilder findActionBuilder(String actionName) { for (ActionBuilder builder : actionBuilders) if (actionName.equals(builder.getName())) return builder; return null; } private Control getActionsTabControl(Composite parent) { Composite tabComposite = EditorUtils.getNamedTabComposite(parent, Messages.actions); ActionsTable table = new ActionsTable(this, actionBuilders, actionArtifactBuilders, cspec, !isSaveAsAllowed()); table.addFieldModifyListener(compoundModifyListener); actionsEditor = new OnePageTableEditor<ActionBuilder>(tabComposite, table, false, SWT.NONE); actionsTable = table; return EditorUtils.getOptimizedControl(tabComposite); } private Control getArtifactsTabControl(Composite parent) { Composite tabComposite = EditorUtils.getNamedTabComposite(parent, Messages.artifacts); ArtifactsTable table = new ArtifactsTable(this, artifactBuilders, cspec, !isSaveAsAllowed()); table.addFieldModifyListener(compoundModifyListener); artifactsEditor = new OnePageTableEditor<ArtifactBuilder>(tabComposite, table, false, SWT.NONE); return EditorUtils.getOptimizedControl(tabComposite); } private Control getAttributesTabControl(Composite parent) { Composite tabComposite = EditorUtils.getNamedTabComposite(parent, Messages.all_attributes); attributesView = new AllAttributesView(tabComposite, SWT.NONE, this); return EditorUtils.getOptimizedControl(tabComposite); } private String getCSpecXML() { String cspecXML = ""; //$NON-NLS-1$ try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); Utils.serialize(cspec.createCSpec(), baos); cspecXML = baos.toString(); } catch (Exception e) { // nothing } return cspecXML; } @SuppressWarnings("unchecked") private Control getDependenciesTabControl(Composite parent) { Composite tabComposite = EditorUtils.getNamedTabComposite(parent, Messages.dependencies); DependenciesTable table = new DependenciesTable(dependencyBuilders, cspec, !isSaveAsAllowed()); table.addTableModifyListener(compoundModifyListener); dependenciesEditor = new SimpleTableEditor<ComponentRequestBuilder>(tabComposite, table, null, Messages.cspec_editor_dependency, null, null, SWT.NONE); return EditorUtils.getOptimizedControl(tabComposite); } private Control getDocumentationTabControl(Composite parent) { Composite tabComposite = EditorUtils.getNamedTabComposite(parent, Messages.documentation); Composite descComposite = new Composite(tabComposite, SWT.NONE); GridLayout layout = new GridLayout(2, false); layout.marginHeight = layout.marginWidth = 0; descComposite.setLayout(layout); descComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); UiUtils.createGridLabel(descComposite, Messages.short_description_with_colon, 1, 0, SWT.NONE); shortDesc = UiUtils.createGridText(descComposite, 1, 0, isSaveAsAllowed() ? SWT.NONE : SWT.READ_ONLY, compoundModifyListener); Label label = UiUtils.createGridLabel(descComposite, Messages.documentation_with_colon, 1, 0, SWT.NONE); label.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, false, false)); documentation = UiUtils.createGridText(descComposite, 1, 0, (isSaveAsAllowed() ? SWT.NONE : SWT.READ_ONLY) | SWT.MULTI | SWT.V_SCROLL, compoundModifyListener); documentation.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); return EditorUtils.getOptimizedControl(tabComposite); } @SuppressWarnings("unchecked") private Control getGeneratorsTabControl(Composite parent) { Composite tabComposite = EditorUtils.getNamedTabComposite(parent, Messages.generators); GeneratorsTable table = new GeneratorsTable(this, generatorBuilders, cspec, !isSaveAsAllowed()); table.addTableModifyListener(compoundModifyListener); generatorsEditor = new SimpleTableEditor<GeneratorBuilder>(tabComposite, table, null, Messages.cspec_editor_generator, null, null, SWT.NONE); return EditorUtils.getOptimizedControl(tabComposite); } private Control getGroupsTabControl(Composite parent) { Composite tabComposite = EditorUtils.getNamedTabComposite(parent, Messages.groups); GroupsTable table = new GroupsTable(this, groupBuilders, cspec, !isSaveAsAllowed()); table.addFieldModifyListener(compoundModifyListener); groupsEditor = new OnePageTableEditor<GroupBuilder>(tabComposite, table, false, SWT.NONE); return EditorUtils.getOptimizedControl(tabComposite); } private Control getMainTabControl(CTabFolder parent) { Composite tabComposite = EditorUtils.getNamedTabComposite(parent, Messages.main); Composite nameComposite = new Composite(tabComposite, SWT.NONE); GridLayout layout = new GridLayout(2, false); layout.marginRight = 8; layout.marginHeight = layout.marginWidth = 0; nameComposite.setLayout(layout); nameComposite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); Label label = UiUtils.createGridLabel(nameComposite, Messages.component_name_with_colon, 1, 0, SWT.NONE); int labelWidth = label.computeSize(SWT.DEFAULT, SWT.DEFAULT).x + 5; GridData gridData = new GridData(SWT.FILL, SWT.FILL, false, false); gridData.widthHint = labelWidth; label.setLayoutData(gridData); componentName = UiUtils.createGridText(nameComposite, 1, 0, isSaveAsAllowed() ? SWT.NONE : SWT.READ_ONLY, compoundModifyListener); UiUtils.createGridLabel(nameComposite, Messages.component_type_with_colon, 1, 0, SWT.NONE); componentType = UiUtils.createGridCombo(nameComposite, 1, 0, !isSaveAsAllowed(), null, null, SWT.DROP_DOWN | SWT.READ_ONLY | SWT.SIMPLE); componentType.setItems(AbstractComponentType.getComponentTypeIDs(true)); componentType.addModifyListener(compoundModifyListener); /* * // not nice but I had to make equal 2 columns form different * Composites // the purpose of hlpComposite is to create empty space, * the same size // as componentCategory * UiUtils.createEmptyPanel(nameComposite); * * int textWidth = componentCategory.computeSize(SWT.DEFAULT, * SWT.DEFAULT).x; gridData = * (GridData)componentCategory.getLayoutData(); gridData.widthHint = * textWidth; componentCategory.setLayoutData(gridData); */ Group versionGroup = new Group(tabComposite, SWT.NONE); versionGroup.setText(Messages.version); layout = new GridLayout(2, false); versionGroup.setLayout(layout); versionGroup.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); Label versionLabel = UiUtils.createGridLabel(versionGroup, Messages.version_with_colon, 1, 0, SWT.NONE); gridData = (GridData) versionLabel.getLayoutData(); gridData.widthHint = labelWidth - layout.marginWidth - 3; versionLabel.setLayoutData(gridData); versionString = UiUtils.createGridText(versionGroup, 1, 0, isSaveAsAllowed() ? SWT.NONE : SWT.READ_ONLY, compoundModifyListener); /* * gridData = (GridData)versionString.getLayoutData(); * gridData.widthHint = textWidth; * versionString.setLayoutData(gridData); * * UiUtils.createEmptyPanel(versionGroup); */ UiUtils.createGridLabel(versionGroup, Messages.type_with_colon, 1, 0, SWT.NONE); versionType = UiUtils.createGridCombo(versionGroup, 1, 0, !isSaveAsAllowed(), null, null, SWT.DROP_DOWN | SWT.READ_ONLY | SWT.SIMPLE); List<VersionType> knownTypes = VersionHelper.getKnownTypes(); int idx = knownTypes.size(); String[] versionTypes = new String[idx]; while (--idx >= 0) versionTypes[idx] = knownTypes.get(idx).getId(); versionType.setItems(versionTypes); versionType.select(versionType.indexOf("OSGi")); //$NON-NLS-1$ versionType.addModifyListener(compoundModifyListener); /* * UiUtils.createEmptyPanel(versionGroup); */ return EditorUtils.getOptimizedControl(tabComposite); } private Control getXMLTabControl(Composite parent) { Composite tabComposite = EditorUtils.getNamedTabComposite(parent, Messages.xml_content); Composite xmlComposite = new Composite(tabComposite, SWT.NONE); GridLayout layout = new GridLayout(); layout.marginHeight = layout.marginWidth = 0; xmlComposite.setLayout(layout); xmlComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); xml = UiUtils.createGridText(xmlComposite, 1, 0, SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL | SWT.READ_ONLY, null); xml.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); return EditorUtils.getOptimizedControl(tabComposite); } private void refreshValues() { setDirty(false); mute = true; try { componentName.setText(TextUtils.notNullString(cspec.getName())); componentType.select(componentType.indexOf(TextUtils.notNullString(cspec.getComponentTypeID()))); Version version = cspec.getVersion(); if (version == null) { versionString.setText(""); //$NON-NLS-1$ versionType.select(versionType.indexOf(VersionType.OSGI)); } else { versionString.setText(TextUtils.notNullString(VersionHelper.getHumanReadable(version))); versionType.select(versionType.indexOf(VersionHelper.getVersionType(version).getId())); } actionBuilders.clear(); actionArtifactBuilders.clear(); artifactBuilders.clear(); groupBuilders.clear(); Map<String, AttributeBuilder> attributesMap = cspec.getAttributes(); if (attributesMap != null) { AttributeBuilder[] builders = attributesMap.values().toArray(new AttributeBuilder[0]); Arrays.sort(builders, CSpecEditorUtils.getAttributeComparator()); List<ActionArtifactBuilder> tmp_actionArtifactBuilders = new ArrayList<ActionArtifactBuilder>(); for (AttributeBuilder attribute : builders) { if (attribute instanceof ActionBuilder) { actionBuilders.add((ActionBuilder) attribute); } else if (attribute instanceof ActionArtifactBuilder) { tmp_actionArtifactBuilders.add((ActionArtifactBuilder) attribute); } else if (attribute instanceof ArtifactBuilder) { artifactBuilders.add((ArtifactBuilder) attribute); } else if (attribute instanceof GroupBuilder) { groupBuilders.add((GroupBuilder) attribute); } } for (ActionArtifactBuilder builder : tmp_actionArtifactBuilders) { addToActionArtifactBuilderMap(builder); } } dependencyBuilders.clear(); Collection<ComponentRequestBuilder> dependencies = cspec.getDependencies(); if (dependencies != null) { ComponentRequestBuilder[] builders = dependencies.toArray(new ComponentRequestBuilder[0]); Arrays.sort(builders, CSpecEditorUtils.getComponentComparator()); for (ComponentRequestBuilder dependency : builders) { dependencyBuilders.add(dependency); } } generatorBuilders.clear(); Collection<GeneratorBuilder> generatorsSet = cspec.getGeneratorList(); if (generatorsSet != null) { GeneratorBuilder[] generators = generatorsSet.toArray(new GeneratorBuilder[0]); Arrays.sort(generators, CSpecEditorUtils.getCSpecElementComparator()); for (GeneratorBuilder generator : generators) { generatorBuilders.add(generator); } } shortDesc.setText(TextUtils.notNullString(cspec.getShortDesc())); Documentation doc = cspec.getDocumentation(); documentation.setText(TextUtils.notNullString(doc == null ? "" //$NON-NLS-1$ : doc.toString())); xml.setText(getCSpecXML()); actionsEditor.refresh(); artifactsEditor.refresh(); groupsEditor.refresh(); dependenciesEditor.refresh(); generatorsEditor.refresh(); needsRefresh = false; } finally { mute = false; } } private void saveToPath(IPath path) { try { SaveRunnable sr = new SaveRunnable(cspec.createCSpec(), path); getSite().getWorkbenchWindow().run(true, true, sr); setInputWithNotify(sr.getSavedInput()); setDirty(false); setPartName(path.lastSegment()); firePropertyChange(IWorkbenchPart.PROP_TITLE); } catch (InvocationTargetException e) { CoreException t = BuckminsterException.wrap(e); String msg = NLS.bind(Messages.unable_to_save_file_0, path); CorePlugin.getLogger().error(t, msg); ErrorDialog.openError(getSite().getShell(), null, msg, t.getStatus()); } catch (InterruptedException e) { } } private void setDirty(boolean flag) { if (readOnly || mute || hasChanges == flag) return; hasChanges = flag; firePropertyChange(PROP_DIRTY); } }