| /******************************************************************************* |
| * Copyright (c) 2007-2019 Cisco Systems, Inc. |
| * 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: |
| * E. Dillon (Cisco Systems, Inc.) - reformat for Code Open-Sourcing |
| *******************************************************************************/ |
| package org.eclipse.tigerstripe.workbench.ui.internal.editors.descriptor.dependencies; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.apache.commons.lang.StringUtils; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.jdt.core.ElementChangedEvent; |
| import org.eclipse.jdt.core.IElementChangedListener; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.IJavaElementDelta; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.layout.GridDataFactory; |
| import org.eclipse.jface.layout.GridLayoutFactory; |
| import org.eclipse.jface.viewers.CheckboxTableViewer; |
| import org.eclipse.jface.viewers.IStructuredContentProvider; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.ITableLabelProvider; |
| import org.eclipse.jface.viewers.LabelProvider; |
| import org.eclipse.jface.viewers.Viewer; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.Table; |
| import org.eclipse.swt.widgets.TableItem; |
| import org.eclipse.tigerstripe.workbench.TigerstripeException; |
| import org.eclipse.tigerstripe.workbench.internal.api.impl.AbstractTigerstripeProjectHandle; |
| import org.eclipse.tigerstripe.workbench.internal.api.impl.TigerstripeProjectHandle; |
| import org.eclipse.tigerstripe.workbench.internal.core.module.InstalledModule; |
| import org.eclipse.tigerstripe.workbench.internal.core.project.Dependency; |
| import org.eclipse.tigerstripe.workbench.internal.core.project.InternalTigerstripeProject; |
| import org.eclipse.tigerstripe.workbench.internal.core.project.ModelReference; |
| import org.eclipse.tigerstripe.workbench.project.IDependency; |
| import org.eclipse.tigerstripe.workbench.project.IModelReference; |
| import org.eclipse.tigerstripe.workbench.project.ITigerstripeModelProject; |
| import org.eclipse.tigerstripe.workbench.project.ITigerstripeModelProjectInternal; |
| import org.eclipse.tigerstripe.workbench.ui.EclipsePlugin; |
| import org.eclipse.tigerstripe.workbench.ui.components.md.MasterDetails; |
| import org.eclipse.tigerstripe.workbench.ui.components.md.MasterDetailsBuilder; |
| import org.eclipse.tigerstripe.workbench.ui.internal.dialogs.CustomTigerstripeDependenciesManager; |
| import org.eclipse.tigerstripe.workbench.ui.internal.dialogs.IProjectSelectionDialog; |
| import org.eclipse.tigerstripe.workbench.ui.internal.dialogs.TigerstripeProjectSelectionDialog; |
| import org.eclipse.tigerstripe.workbench.ui.internal.editors.TigerstripeFormPage; |
| import org.eclipse.tigerstripe.workbench.ui.internal.editors.descriptor.DescriptorEditor; |
| import org.eclipse.tigerstripe.workbench.ui.internal.editors.descriptor.TigerstripeDescriptorSectionPart; |
| import org.eclipse.tigerstripe.workbench.ui.internal.utils.TigerstripeLayoutFactory; |
| import org.eclipse.ui.forms.IManagedForm; |
| import org.eclipse.ui.forms.widgets.ExpandableComposite; |
| import org.eclipse.ui.forms.widgets.FormToolkit; |
| |
| /** |
| * Section used to define Tigerstripe dependencies. Look under tigerstripe.xml > |
| * Dependencies |
| * |
| * @author nmehrega |
| */ |
| public class ReferencedProjectsSection extends TigerstripeDescriptorSectionPart { |
| |
| private CheckboxTableViewer viewer; |
| |
| private Button removeButton; |
| |
| private Button selectAllButton; |
| |
| private Button deselectAllButton; |
| |
| private MasterDetails masterDetails; |
| |
| private ClasspathChangesListener classpathListener; |
| |
| private Button modifyRuntimeDependencies; |
| |
| private static final String DEP_CHECKBOX_LABEL = "Modify dependencies at generation time (advanced)"; |
| |
| private static final String ADVANCED_PROPERTY_MODIFY_DEP_AT_RUNTIME = "modifyDependenciesAtGenerationTime"; |
| |
| private class ClasspathChangesListener implements IElementChangedListener { |
| |
| public void elementChanged(ElementChangedEvent event) { |
| IJavaElementDelta delta = event.getDelta(); |
| IJavaElementDelta[] childs = delta.getAffectedChildren(); |
| for (IJavaElementDelta child : childs) { |
| if (child.getElement().getElementType() == IJavaElement.JAVA_PROJECT) { |
| IJavaProject jProject = (IJavaProject) child.getElement(); |
| if (isCurrentProject(jProject) && isClassPathChanged(child)) { |
| resolveReferencedModels(); |
| refreshReferences(); |
| } |
| } |
| } |
| } |
| |
| private boolean isCurrentProject(IJavaProject jProject) { |
| IJavaProject jTsProject = getTSProject().getAdapter(IJavaProject.class); |
| return jTsProject != null && jTsProject.equals(jProject); |
| } |
| |
| private boolean isClassPathChanged(IJavaElementDelta delta) { |
| return (delta.getFlags() & IJavaElementDelta.F_CLASSPATH_CHANGED) != 0 |
| || (delta.getFlags() & IJavaElementDelta.F_RESOLVED_CLASSPATH_CHANGED) != 0; |
| } |
| |
| private void resolveReferencedModels() { |
| try { |
| IModelReference[] references = getTSProject().getModelReferences(); |
| for (IModelReference reference : references) { |
| reference.getResolvedModel(); |
| } |
| } catch (TigerstripeException e) { |
| EclipsePlugin.log(e); |
| } |
| } |
| |
| private void refreshReferences() { |
| Control control = viewer.getControl(); |
| if (!control.isDisposed()) { |
| control.getDisplay().asyncExec(ReferencedProjectsSection.this::refresh); |
| } |
| } |
| } |
| |
| static class ReferencedProjectsContentProvider implements IStructuredContentProvider { |
| public Object[] getElements(Object inputElement) { |
| |
| if (inputElement instanceof ITigerstripeModelProject) { |
| ITigerstripeModelProject project = (ITigerstripeModelProject) inputElement; |
| try { |
| IModelReference[] modelReferences = project.getModelReferences(); |
| IDependency[] dependencies = project.getDependencies(); |
| Object[] elements = new Object[modelReferences.length + dependencies.length]; |
| System.arraycopy(modelReferences, 0, elements, 0, modelReferences.length); |
| System.arraycopy(dependencies, 0, elements, modelReferences.length, dependencies.length); |
| return elements; |
| } catch (TigerstripeException e) { |
| return new Object[0]; |
| } |
| } |
| return new Object[0]; |
| } |
| |
| public void dispose() { |
| // N/A |
| } |
| |
| public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { |
| // N/A |
| } |
| } |
| |
| static class ReferencedProjectsLabelProvider extends LabelProvider implements ITableLabelProvider { |
| |
| public String getColumnText(Object obj, int index) { |
| |
| if (obj instanceof ModelReference) { |
| ModelReference ref = (ModelReference) obj; |
| |
| String modelId = ref.getToModelId(); |
| String projectName = null; |
| String version = null; |
| if (ref.isResolved()) { |
| ITigerstripeModelProject project = ref.getResolvedModel(); |
| projectName = project.getName(); |
| try { |
| version = project.getProjectDetails().getVersion(); |
| } catch (Exception e) { |
| } |
| } |
| |
| StringBuilder buffer = new StringBuilder(); |
| if (modelId != null && modelId.length() > 0) { |
| buffer.append(modelId); |
| } else { |
| buffer.append(projectName); |
| } |
| |
| if (version != null && version.length() > 0) { |
| buffer.append(" ("); |
| buffer.append(version); |
| buffer.append(")"); |
| } |
| |
| return buffer.toString(); |
| |
| } else if (obj instanceof IDependency) { |
| return ((IDependency) obj).getPath(); |
| } else { |
| return "Unknown"; |
| } |
| } |
| |
| public Image getColumnImage(Object obj, int index) { |
| return getImage(obj); |
| } |
| |
| @Override |
| public String getText(Object obj) { |
| return getColumnText(obj, 0); |
| } |
| |
| @Override |
| public Image getImage(Object obj) { |
| return IMAGE_PROVIDER.getImage(obj); |
| } |
| } |
| |
| public ReferencedProjectsSection(TigerstripeFormPage page, Composite parent, FormToolkit toolkit) { |
| super(page, parent, toolkit, ExpandableComposite.TITLE_BAR); |
| setTitle("Dependencies"); |
| } |
| |
| @Override |
| public void initialize(IManagedForm form) { |
| super.initialize(form); |
| createContent(); |
| initializeDependencyEnablement(); |
| |
| classpathListener = new ClasspathChangesListener(); |
| JavaCore.addElementChangedListener(classpathListener, ElementChangedEvent.POST_CHANGE); |
| } |
| |
| private void initializeDependencyEnablement() { |
| |
| InternalTigerstripeProject tsProject = getActualTSProject(); |
| String enableModificationOfDepAtRuntime = null; |
| |
| if (tsProject != null) |
| enableModificationOfDepAtRuntime = tsProject.getAdvancedProperty(ADVANCED_PROPERTY_MODIFY_DEP_AT_RUNTIME); |
| |
| if (enableModificationOfDepAtRuntime != null && enableModificationOfDepAtRuntime.equalsIgnoreCase("true")) { |
| modifyRuntimeDependencies.setSelection(true); |
| int numOfDependencies = viewer.getTable().getItemCount(); |
| for (int i = 0; i < numOfDependencies; i++) { |
| Object element = viewer.getElementAt(i); |
| if (element instanceof ModelReference) { |
| ModelReference reference = (ModelReference) element; |
| viewer.setChecked(reference, reference.isEnabled()); |
| |
| } else if (element instanceof IDependency) { |
| IDependency dependency = (IDependency) element; |
| viewer.setChecked(dependency, dependency.isEnabled()); |
| } |
| } |
| |
| selectAllButton.setEnabled(true); |
| deselectAllButton.setEnabled(true); |
| |
| } else { |
| // Dependency modification at runtime is off |
| modifyRuntimeDependencies.setSelection(false); |
| selectAllButton.setEnabled(false); |
| deselectAllButton.setEnabled(false); |
| |
| viewer.setAllChecked(true); |
| } |
| } |
| |
| |
| // TODO - Why do we need access to the internal project? Can we abstract it behind the interface? |
| private InternalTigerstripeProject getActualTSProject() { |
| Object input = viewer.getInput(); |
| |
| if (input instanceof TigerstripeProjectHandle) { |
| try { |
| return (InternalTigerstripeProject) ((TigerstripeProjectHandle) input).getTSProject(); |
| } catch (TigerstripeException e) { |
| EclipsePlugin.logErrorMessage("Problem occured while getting Tigerstripe Project: " |
| + StringUtils.defaultString(e.getMessage()), e); |
| } |
| } |
| return null; |
| } |
| |
| @Override |
| public void dispose() { |
| if (classpathListener != null) { |
| JavaCore.removeElementChangedListener(classpathListener); |
| EclipsePlugin.getTigerStripeDependenciesManager().fireDisposed(getTSProject()); |
| } |
| super.dispose(); |
| } |
| |
| @Override |
| protected void createContent() { |
| GridDataFactory.fillDefaults().grab(true, true).applyTo(getSection()); |
| GridLayoutFactory.fillDefaults().applyTo(getSection()); |
| GridLayoutFactory.fillDefaults().applyTo(getBody()); |
| getSection().setClient(getBody()); |
| |
| Composite parent = getToolkit().createComposite(getBody()); |
| GridDataFactory.fillDefaults().grab(true, true).applyTo(parent); |
| GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(true).applyTo(parent); |
| |
| Composite masterContainer = getToolkit().createComposite(parent); |
| Composite detailsContainer = getToolkit().createComposite(parent, SWT.NONE); |
| GridLayoutFactory.fillDefaults().margins(1, 1).numColumns(2).applyTo(masterContainer); |
| GridLayoutFactory.fillDefaults().applyTo(detailsContainer); |
| GridDataFactory.fillDefaults().grab(true, true).applyTo(masterContainer); |
| GridDataFactory.fillDefaults().grab(true, true).applyTo(detailsContainer); |
| |
| createTable(masterContainer, getToolkit()); |
| |
| modifyRuntimeDependencies = new Button(parent, SWT.CHECK); |
| modifyRuntimeDependencies.setEnabled(true); |
| modifyRuntimeDependencies.setText(DEP_CHECKBOX_LABEL); |
| modifyRuntimeDependencies.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| InternalTigerstripeProject tsProject = getActualTSProject(); |
| |
| if (tsProject != null) { |
| tsProject.setAdvancedProperty(ADVANCED_PROPERTY_MODIFY_DEP_AT_RUNTIME, |
| modifyRuntimeDependencies.getSelection() ? "true" : "false"); |
| } |
| |
| if (modifyRuntimeDependencies.getSelection()) { |
| selectAllButton.setEnabled(true); |
| deselectAllButton.setEnabled(true); |
| if (tsProject != null) { |
| tsProject.setDirty(); |
| } |
| } else { |
| enableAllDependencies(true); |
| selectAllButton.setEnabled(false); |
| deselectAllButton.setEnabled(false); |
| } |
| markPageModified(); |
| } |
| |
| }); |
| |
| getToolkit().paintBordersFor(masterContainer); |
| |
| masterDetails = MasterDetailsBuilder.create() |
| .addDetail(ModelReference.class, new ReferenceDetails(getToolkit(), detailsContainer)) |
| .addDetail(Dependency.class, new DependencyDetails(getToolkit(), detailsContainer)).build(); |
| } |
| |
| private void enableAllDependencies(boolean markAsDirty) { |
| |
| boolean stateChanged = false; |
| |
| // Walk through all dependencies and enable them. |
| int numOfDependencies = viewer.getTable().getItemCount(); |
| for (int i = 0; i < numOfDependencies; i++) { |
| TableItem item = viewer.getTable().getItem(i); |
| if (!item.getChecked()) { |
| stateChanged = true; |
| item.setChecked(true); |
| Object element = viewer.getElementAt(i); |
| if (element instanceof ModelReference) { |
| ModelReference reference = (ModelReference) element; |
| reference.setEnabled(true); |
| } else if (element instanceof IDependency) { |
| IDependency dependency = (IDependency) element; |
| dependency.setEnabled(true); |
| } |
| } |
| } |
| |
| InternalTigerstripeProject tsProject = getActualTSProject(); |
| if (stateChanged && markAsDirty && tsProject != null) { |
| tsProject.setDirty(); |
| markPageModified(); |
| Object input = viewer.getInput(); |
| if (input instanceof TigerstripeProjectHandle) { |
| ((TigerstripeProjectHandle) input).markCacheAsDirty(); |
| } |
| } |
| } |
| |
| private void disableAllDependencies() { |
| |
| boolean stateChanged = false; |
| |
| // Walk through all dependencies and enable them. |
| int numOfDependencies = viewer.getTable().getItemCount(); |
| for (int i = 0; i < numOfDependencies; i++) { |
| TableItem item = viewer.getTable().getItem(i); |
| if (item.getChecked()) { |
| stateChanged = true; |
| item.setChecked(false); |
| Object element = viewer.getElementAt(i); |
| if (element instanceof ModelReference) { |
| ModelReference reference = (ModelReference) element; |
| reference.setEnabled(false); |
| } else if (element instanceof IDependency) { |
| IDependency dependency = (IDependency) element; |
| dependency.setEnabled(false); |
| } |
| } |
| } |
| |
| InternalTigerstripeProject tsProject = getActualTSProject(); |
| if (stateChanged && tsProject != null) { |
| tsProject.setDirty(); |
| markPageModified(); |
| Object input = viewer.getInput(); |
| if (input instanceof TigerstripeProjectHandle) { |
| ((TigerstripeProjectHandle) input).markCacheAsDirty(); |
| } |
| } |
| } |
| |
| private void createTable(Composite parent, FormToolkit toolkit) { |
| Table t = toolkit.createTable(parent, SWT.NULL | SWT.MULTI | SWT.CHECK); |
| GridData gd = new GridData(GridData.FILL_BOTH); |
| gd.verticalSpan = 2; |
| t.setLayoutData(gd); |
| |
| Composite buttonsClient = toolkit.createComposite(parent); |
| buttonsClient.setLayout(TigerstripeLayoutFactory.createButtonsGridLayout()); |
| buttonsClient.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING)); |
| |
| // Add Dependency button |
| Button addButton = toolkit.createButton(buttonsClient, "Add...", SWT.PUSH); |
| addButton.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| addButtonSelected(); |
| } |
| }); |
| addButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| |
| // Add Missing Transitive Dependency button |
| // Need to disable this function in the case where the "custom dependency Dialog" is set? |
| if (CustomTigerstripeDependenciesManager.isTransitiveSupported()) { |
| Button addMissingTransitiveDependenciesButton = toolkit.createButton(buttonsClient, "Add Transitive", SWT.PUSH); |
| addMissingTransitiveDependenciesButton.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| addMissingTransitiveDependenciesButtonSelected(); |
| } |
| }); |
| addMissingTransitiveDependenciesButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| } |
| // Remove Dependency button |
| removeButton = toolkit.createButton(buttonsClient, "Remove", SWT.PUSH); |
| removeButton.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| removeButtonSelected(); |
| } |
| }); |
| removeButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| |
| // Select All button |
| selectAllButton = toolkit.createButton(buttonsClient, "Select All", SWT.PUSH); |
| selectAllButton.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| enableAllDependencies(true); |
| } |
| }); |
| selectAllButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| |
| // Deselect All button |
| deselectAllButton = toolkit.createButton(buttonsClient, "Deselect All", SWT.PUSH); |
| deselectAllButton.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| disableAllDependencies(); |
| } |
| }); |
| deselectAllButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| |
| viewer = new CheckboxTableViewer(t); |
| viewer.addSelectionChangedListener(event -> { |
| updateDetails(); |
| updateButtonsEnablement(); |
| }); |
| viewer.setContentProvider(new ReferencedProjectsContentProvider()); |
| final ITableLabelProvider labelProvider = new ReferencedProjectsLabelProvider(); |
| viewer.setLabelProvider(labelProvider); |
| ITextProvider textAdapter = obj -> labelProvider.getColumnText(obj, 0); |
| viewer.setComparator(new DependenciesSorter(textAdapter, DEPENDENCY_KIND_RESOLVER)); |
| |
| AbstractTigerstripeProjectHandle handle = (AbstractTigerstripeProjectHandle) getTSProject(); |
| viewer.setInput(handle); |
| |
| viewer.addCheckStateListener(event -> { |
| if (!modifyRuntimeDependencies.getSelection()) { |
| MessageDialog.openInformation(Display.getCurrent().getActiveShell(), "Operation Not Enabled", |
| "To modify dependencies at generation time (i.e. run generation on certain modules), you'll need to explicitly enable the option below: '" |
| + DEP_CHECKBOX_LABEL + "'"); |
| viewer.setChecked(event.getElement(), true); |
| } else { |
| getActualTSProject().setDirty(); |
| |
| Object source = event.getElement(); |
| if (source instanceof IDependency) { |
| ((IDependency) source).setEnabled(event.getChecked()); |
| } else if (source instanceof ModelReference) { |
| ((ModelReference) source).setEnabled(event.getChecked()); |
| } |
| |
| Object input = viewer.getInput(); |
| if (input instanceof TigerstripeProjectHandle) { |
| ((TigerstripeProjectHandle) input).markCacheAsDirty(); |
| } |
| |
| markPageModified(); |
| } |
| }); |
| |
| } |
| |
| protected void addButtonSelected() { |
| Set<String> filteredOutProjects = new HashSet<>(); |
| |
| try { |
| // the current project |
| filteredOutProjects.add(getTSProject().getModelId()); |
| // existing Refs |
| for (IModelReference prjRef : getTSProject().getModelReferences()) { |
| filteredOutProjects.add(prjRef.getToModelId()); |
| } |
| } catch (TigerstripeException e) { |
| // ignore here |
| } |
| |
| IProjectSelectionDialog dialog = null; |
| |
| // Here we override the default dialog if appropriate extension point is |
| // implemented |
| if (CustomTigerstripeDependenciesManager.hasCustomDialog()) { |
| try { |
| dialog = CustomTigerstripeDependenciesManager.make(getSection().getShell(), filteredOutProjects, |
| getTSProject()); |
| } catch (TigerstripeException e) { |
| EclipsePlugin.logErrorMessage("Custom Dependencies Dialog Load Error", e); |
| } |
| } |
| |
| if (dialog == null) { |
| dialog = new TigerstripeProjectSelectionDialog(getSection().getShell(), filteredOutProjects, |
| getTSProject()); |
| } |
| |
| if (dialog.open() == Window.OK) { |
| Object[] results = dialog.getResult(); |
| for (Object res : results) { |
| String modelId = null; |
| if (res instanceof IJavaProject) { |
| IJavaProject prj = (IJavaProject) res; |
| |
| ITigerstripeModelProject tsPrj = prj.getProject().getAdapter(ITigerstripeModelProject.class); |
| if (tsPrj != null) { |
| try { |
| modelId = tsPrj.getModelId(); |
| } catch (TigerstripeException e) { |
| EclipsePlugin.logErrorMessage("Failed to parse model ID from project: " + tsPrj.getName(), e); |
| } |
| } |
| } else if (res instanceof InstalledModule) { |
| InstalledModule module = (InstalledModule) res; |
| modelId = module.getModuleID(); |
| } else if (res instanceof String) { |
| modelId = (String)res; |
| } |
| if (StringUtils.isNotEmpty(modelId)) { |
| try { |
| |
| IModelReference ref = null; |
| for (IModelReference existingRef : getTSProject().getModelReferences()) { |
| if (StringUtils.equals(existingRef.getToModelId(), modelId)) { |
| ref = existingRef; |
| break; |
| } |
| } |
| |
| if (ref == null) { |
| ref = getTSProject().addModelReference(modelId); |
| } |
| viewer.refresh(true); |
| viewer.setChecked(ref, true); // NM: Check newly added |
| // dependency |
| markPageModified(); |
| if (dialog.isIncludeTransitiveDependencies()) { |
| addMissingTransitiveDependencies(new IModelReference[] { ref }); |
| } |
| dialog.addMavenDependency(); |
| } catch (TigerstripeException e) { |
| EclipsePlugin.log(e); |
| } |
| continue; |
| } |
| if (res instanceof IResource) { |
| try { |
| IDependency dep = getTSProject() |
| .makeDependency(((IResource) res).getProjectRelativePath().toOSString()); |
| getTSProject().addDependency(dep, new NullProgressMonitor()); |
| viewer.refresh(true); |
| viewer.setChecked(dep, true); // NM: Check newly added |
| // dependency |
| markPageModified(); |
| } catch (TigerstripeException e) { |
| EclipsePlugin.log(e); |
| } |
| } |
| } |
| |
| } |
| viewer.refresh(); |
| } |
| |
| protected void addMissingTransitiveDependenciesButtonSelected() { |
| |
| // Take the list of current Dependencies and work out |
| // the list of "missing" transitive" dependencies |
| // these could be project, or modules |
| // check for circular/repeats. |
| // Add the ones found, and highlight any not found in a dialog. |
| |
| try { |
| IModelReference[] references = getTSProject().getModelReferences(); |
| addMissingTransitiveDependencies(references); |
| } catch (TigerstripeException e) { |
| EclipsePlugin.log(e); |
| } |
| |
| } |
| |
| protected void addMissingTransitiveDependencies(IModelReference[] references) { |
| |
| try { |
| Set<String> existingModels = new HashSet<>(); |
| IModelReference[] existingReferences = getTSProject().getModelReferences(); |
| for (IModelReference ref : existingReferences) { |
| existingModels.add(ref.getToModelId()); |
| } |
| existingModels.add(getTSProject().getModelId()); |
| |
| List<IModelReference> newRefs = new ArrayList<>(); |
| for (IModelReference ref : references) { |
| newRefs.addAll(getTransitiveRefs(ref)); |
| } |
| |
| // deDuplicate |
| Set<String> referencedModels = new HashSet<>(); |
| for (IModelReference ref : newRefs) { |
| if (!existingModels.contains(ref.getToModelId())) { |
| referencedModels.add(ref.getToModelId()); |
| } |
| } |
| |
| // set on the model... |
| for (String ref : referencedModels) { |
| IModelReference newRef = getTSProject().addModelReference(ref); |
| if (newRef.getResolvedModel() != null) { |
| viewer.refresh(true); |
| viewer.setChecked(newRef, true); // NM: Check newly added |
| // dependency |
| markPageModified(); |
| } |
| |
| } |
| |
| } catch (TigerstripeException e) { |
| EclipsePlugin.log(e); |
| } |
| |
| } |
| |
| // recurse on the transitive dependencies |
| |
| private static List<IModelReference> getTransitiveRefs(IModelReference modelRef) throws TigerstripeException { |
| List<IModelReference> newRefs = new ArrayList<>(); |
| if (modelRef.getResolvedModel() != null) { |
| List<IModelReference> addedRefs = Arrays.asList(modelRef.getResolvedModel().getModelReferences()); |
| newRefs.addAll(addedRefs); |
| for (IModelReference ref : addedRefs) { |
| if (!newRefs.contains(ref)) { |
| newRefs.addAll(getTransitiveRefs(ref)); |
| } |
| } |
| } |
| return newRefs; |
| |
| } |
| |
| protected void removeButtonSelected() { |
| TableItem[] selectedItems = viewer.getTable().getSelection(); |
| Map<String, IModelReference> modelRefMap = new HashMap<>(); |
| List<IDependency> dependencyFields = new ArrayList<>(); |
| |
| for (int i = 0; i < selectedItems.length; i++) { |
| Object data = selectedItems[i].getData(); |
| if (data instanceof IModelReference) { |
| IModelReference modelRef = (ModelReference) data; |
| modelRefMap.put(modelRef.getToModelId(), modelRef); |
| } else if (data instanceof IDependency) { |
| dependencyFields.add((IDependency) data); |
| } |
| } |
| |
| String message = "Do you really want to remove "; |
| if (selectedItems.length > 1) { |
| message = message + "these " + selectedItems.length + " items?"; |
| } else { |
| message = message + "this item?"; |
| } |
| |
| MessageDialog msgDialog = new MessageDialog(getBody().getShell(), "Remove Reference/Dependency", null, message, |
| MessageDialog.QUESTION, new String[] { "Yes", "No" }, 1); |
| |
| if (msgDialog.open() == 0) { |
| ITigerstripeModelProjectInternal handle = getTSProject(); |
| try { |
| handle.removeModelReferences(modelRefMap.keySet().stream().toArray(String[]::new)); |
| handle.removeDependencies(dependencyFields.toArray(new IDependency[0]), new NullProgressMonitor()); |
| } catch (TigerstripeException e) { |
| EclipsePlugin.log(e); |
| } |
| EclipsePlugin.getTigerStripeDependenciesManager().fireRemoveDependencies(getTSProject(), modelRefMap); |
| markPageModified(); |
| viewer.refresh(true); |
| } |
| } |
| |
| protected void markPageModified() { |
| DescriptorEditor editor = (DescriptorEditor) getPage().getEditor(); |
| editor.pageModified(); |
| } |
| |
| @Override |
| public void refresh() { |
| if (viewer.getTable().isDisposed()) { |
| return; |
| } |
| updateViewerInput(); |
| |
| updateDetails(); |
| |
| // Don't mark the page as dirty after a refresh. |
| if (!modifyRuntimeDependencies.getSelection()) { |
| enableAllDependencies(false); |
| } |
| |
| updateButtonsEnablement(); |
| } |
| |
| private void updateDetails() { |
| masterDetails.switchTo(((IStructuredSelection) viewer.getSelection()).getFirstElement()); |
| } |
| |
| private void updateButtonsEnablement() { |
| TableItem[] selectedItems = viewer.getTable().getSelection(); |
| removeButton.setEnabled(selectedItems != null && selectedItems.length > 0); |
| } |
| |
| // [nmehrega] Bugzilla 322566: Update the viewer's input if our working copy |
| // of TS Project has changed. |
| // This, for example, happens when the project descriptor is modified and |
| // saved. |
| private void updateViewerInput() { |
| Object tsProjectWorkingCopy = getTSProject(); |
| if (!viewer.getTable().isDisposed()) { |
| viewer.setInput(tsProjectWorkingCopy); |
| initializeDependencyEnablement(); |
| } |
| } |
| |
| private static final IDependencyKindResolver DEPENDENCY_KIND_RESOLVER = obj -> { |
| if (obj instanceof ModelReference) { |
| ModelReference ref = (ModelReference) obj; |
| if (ref.isResolved()) { |
| if (ref.isWorkspaceReference()) { |
| return DependencyKind.PROJECT; |
| } else if (ref.isInstalledModuleReference()) { |
| return DependencyKind.MODULE; |
| } |
| } |
| } |
| if (obj instanceof IDependency) { |
| return DependencyKind.DEPENDENCY; |
| } |
| return DependencyKind.UNKNOWN; |
| }; |
| |
| private static final DependenciesImageProvider IMAGE_PROVIDER = new DependenciesImageProvider( |
| DEPENDENCY_KIND_RESOLVER); |
| } |