blob: 8505db75c3a4a40d612133323e40ecfe71810a69 [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2009 Red Hat
* 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:
* Rob Stryker - initial implementation and ongoing maintenance
******************************************************************************/
package org.eclipse.wst.common.componentcore.ui.propertypage;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.IWorkspaceRunnable;
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.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProviderChangedEvent;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.datamodel.properties.ICreateReferenceComponentsDataModelProperties;
import org.eclipse.wst.common.componentcore.internal.ComponentResource;
import org.eclipse.wst.common.componentcore.internal.DefaultModuleHandler;
import org.eclipse.wst.common.componentcore.internal.DependencyType;
import org.eclipse.wst.common.componentcore.internal.IModuleHandler;
import org.eclipse.wst.common.componentcore.internal.StructureEdit;
import org.eclipse.wst.common.componentcore.internal.WorkbenchComponent;
import org.eclipse.wst.common.componentcore.internal.operation.CreateReferenceComponentsDataModelProvider;
import org.eclipse.wst.common.componentcore.internal.operation.RemoveReferenceComponentsDataModelProvider;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
import org.eclipse.wst.common.componentcore.ui.Messages;
import org.eclipse.wst.common.componentcore.ui.ModuleCoreUIPlugin;
import org.eclipse.wst.common.componentcore.ui.internal.propertypage.ComponentDependencyContentProvider;
import org.eclipse.wst.common.componentcore.ui.internal.propertypage.DependencyPageExtensionManager;
import org.eclipse.wst.common.componentcore.ui.internal.propertypage.DependencyPageExtensionManager.ReferenceExtension;
import org.eclipse.wst.common.componentcore.ui.internal.propertypage.NewReferenceWizard;
import org.eclipse.wst.common.componentcore.ui.internal.taskwizard.TaskWizard;
import org.eclipse.wst.common.componentcore.ui.internal.taskwizard.WizardFragment;
import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.frameworks.datamodel.IDataModelOperation;
import org.eclipse.wst.common.frameworks.datamodel.IDataModelProvider;
public class AddModuleDependenciesPropertiesPage implements Listener,
IModuleDependenciesControl, ILabelProviderListener {
protected static final String DEPLOY_PATH_PROPERTY = new Integer(0).toString();
protected static final String SOURCE_PROPERTY = new Integer(1).toString();
protected final String PATH_SEPARATOR = String.valueOf(IPath.SEPARATOR);
private boolean hasInitialized = false;
protected final IProject project;
protected final ModuleAssemblyRootPage propPage;
protected IVirtualComponent rootComponent = null;
protected Text componentNameText;
protected Label availableModules;
protected TableViewer availableComponentsViewer;
protected Button addMappingButton, addReferenceButton, editReferenceButton, removeButton;
protected Composite buttonColumn;
protected static final IStatus OK_STATUS = IDataModelProvider.OK_STATUS;
//protected Listener tableListener;
protected Listener labelListener;
// Mappings that existed when the page was opened (or last saved)
protected HashMap<IVirtualComponent, String> oldComponentToRuntimePath = new HashMap<IVirtualComponent, String>();
// Mappings that are current
protected HashMap<IVirtualComponent, String> objectToRuntimePath = new HashMap<IVirtualComponent, String>();
protected ArrayList<IVirtualComponent> consumedReferences = new ArrayList<IVirtualComponent>();
// A single list of wb-resource mappings. If there's any change,
// all old will be removed and new ones added
protected ArrayList<ComponentResourceProxy> resourceMappings = new ArrayList<ComponentResourceProxy>();
// keeps track if a change has occurred in wb-resource mappings
protected boolean resourceMappingsChanged = false;
protected IModuleHandler moduleHandler;
/**
* Constructor for AddModulestoEARPropertiesControl.
*/
public AddModuleDependenciesPropertiesPage(final IProject project,
final ModuleAssemblyRootPage page) {
this.project = project;
this.propPage = page;
rootComponent = ComponentCore.createComponent(project);
}
/*
* UI Creation Methods
*/
public Composite createContents(final Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.marginWidth = 0;
layout.marginWidth = 0;
composite.setLayout(layout);
composite.setLayoutData(new GridData(GridData.FILL_BOTH));
createDescriptionComposite(composite);
createListGroup(composite);
refresh();
Dialog.applyDialogFont(parent);
return composite;
}
protected void createDescriptionComposite(Composite parent){
ModuleAssemblyRootPage.createDescriptionComposite(parent, getModuleAssemblyRootPageDescription());
}
protected String getModuleAssemblyRootPageDescription() {
return Messages.ModuleAssemblyRootPageDescription;
}
protected void createListGroup(Composite parent) {
Composite listGroup = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.numColumns = 1;
layout.marginWidth = 0;
layout.marginHeight = 0;
listGroup.setLayout(layout);
GridData gData = new GridData(GridData.FILL_BOTH);
gData.horizontalIndent = 5;
listGroup.setLayoutData(gData);
availableModules = new Label(listGroup, SWT.NONE);
gData = new GridData(GridData.HORIZONTAL_ALIGN_FILL
| GridData.VERTICAL_ALIGN_FILL);
availableModules.setText(Messages.ModuleAssembly);
availableModules.setLayoutData(gData);
createTableComposite(listGroup);
}
protected void createTableComposite(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
GridData gData = new GridData(GridData.FILL_BOTH);
composite.setLayoutData(gData);
fillTableComposite(composite);
}
public void fillTableComposite(Composite parent) {
GridLayout layout = new GridLayout();
layout.numColumns = 2;
layout.marginHeight = 0;
parent.setLayout(layout);
parent.setLayoutData(new GridData(GridData.FILL_BOTH));
createTable(parent);
createButtonColumn(parent);
}
protected void createButtonColumn(Composite parent) {
buttonColumn = createButtonColumnComposite(parent);
GridData data = new GridData(GridData.HORIZONTAL_ALIGN_END);
buttonColumn.setLayoutData(data);
createPushButtons();
}
protected void createPushButtons() {
addReferenceButton = createPushButton(Messages.AddEllipsis);
editReferenceButton = createPushButton(Messages.EditEllipsis);
removeButton = createPushButton(Messages.RemoveSelected);
}
protected Button createPushButton(String label) {
Button aButton = new Button(buttonColumn, SWT.PUSH);
aButton.setText(label);
aButton.addListener(SWT.Selection, this);
aButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
return aButton;
}
public Composite createButtonColumnComposite(Composite parent) {
Composite aButtonColumn = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.numColumns = 1;
layout.marginHeight = 0;
layout.marginWidth = 0;
aButtonColumn.setLayout(layout);
GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL
| GridData.VERTICAL_ALIGN_BEGINNING);
aButtonColumn.setLayoutData(data);
return aButtonColumn;
}
public Group createGroup(Composite parent) {
return new Group(parent, SWT.NULL);
}
protected void createTable(Composite parent) {
if (rootComponent != null) {
availableComponentsViewer = createAvailableComponentsViewer(parent);
GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL
| GridData.FILL_VERTICAL);
availableComponentsViewer.getTable().setLayoutData(gd);
ComponentDependencyContentProvider provider = createProvider();
provider.setRuntimePaths(objectToRuntimePath);
provider.setResourceMappings(resourceMappings);
availableComponentsViewer.setContentProvider(provider);
//availableComponentsViewer.setLabelProvider(new DecoratingLabelProvider(
// new WorkbenchLabelProvider(), PlatformUI.getWorkbench().
// getDecoratorManager().getLabelDecorator()));
availableComponentsViewer.setLabelProvider(provider);
addTableListeners();
}
}
/**
* Subclasses should over-ride this and extend the class
*/
protected ComponentDependencyContentProvider createProvider() {
return new ComponentDependencyContentProvider(this);
}
/*
* Listeners of various events
*/
protected void addTableListeners() {
addHoverHelpListeners();
addDoubleClickListener();
addSelectionListener();
}
protected void addHoverHelpListeners() {
final Table table = availableComponentsViewer.getTable();
createLabelListener(table);
// createTableListener(table);
// table.addListener(SWT.Dispose, tableListener);
// table.addListener(SWT.KeyDown, tableListener);
// table.addListener(SWT.MouseMove, tableListener);
// table.addListener(SWT.MouseHover, tableListener);
}
protected void createLabelListener(final Table table) {
labelListener = new Listener() {
public void handleEvent(Event event) {
Label label = (Label) event.widget;
Shell shell = label.getShell();
switch (event.type) {
case SWT.MouseDown:
Event e = new Event();
e.item = (TableItem) label.getData("_TABLEITEM"); //$NON-NLS-1$
table.setSelection(new TableItem[] { (TableItem) e.item });
table.notifyListeners(SWT.Selection, e);
shell.dispose();
table.setFocus();
break;
case SWT.MouseExit:
shell.dispose();
break;
}
}
};
}
// protected void createTableListener(final Table table) {
// tableListener = new Listener() {
// Shell tip = null;
// Label label = null;
//
// public void handleEvent(Event event) {
// switch (event.type) {
// case SWT.Dispose:
// case SWT.KeyDown:
// case SWT.MouseMove: {
// if (tip == null)
// break;
// tip.dispose();
// tip = null;
// label = null;
// break;
// }
// case SWT.MouseHover: {
// TableItem item = table.getItem(new Point(event.x, event.y));
// if (item != null && item.getData() != null && !canEdit(item.getData())) {
// if (tip != null && !tip.isDisposed())
// tip.dispose();
// tip = new Shell(PlatformUI.getWorkbench()
// .getActiveWorkbenchWindow().getShell(),
// SWT.ON_TOP | SWT.NO_FOCUS | SWT.TOOL);
// tip.setBackground(Display.getDefault().getSystemColor(
// SWT.COLOR_INFO_BACKGROUND));
// FillLayout layout = new FillLayout();
// layout.marginWidth = 2;
// tip.setLayout(layout);
// label = new Label(tip, SWT.WRAP);
// label.setForeground(Display.getDefault()
// .getSystemColor(SWT.COLOR_INFO_FOREGROUND));
// label.setBackground(Display.getDefault()
// .getSystemColor(SWT.COLOR_INFO_BACKGROUND));
// label.setData("_TABLEITEM", item); //$NON-NLS-1$
// label.setText( Messages.InternalLibJarWarning);
// label.addListener(SWT.MouseExit, labelListener);
// label.addListener(SWT.MouseDown, labelListener);
// Point size = tip.computeSize(SWT.DEFAULT, SWT.DEFAULT);
// Rectangle rect = item.getBounds(0);
// Point pt = table.toDisplay(rect.x, rect.y);
// tip.setBounds(pt.x, pt.y - size.y, size.x, size.y);
// tip.setVisible(true);
// }
// }
// }
// }
// };
// }
// protected boolean canEdit(Object data) {
// if( data == null ) return false;
// if( !(data instanceof VirtualArchiveComponent)) return true;
//
// VirtualArchiveComponent d2 = (VirtualArchiveComponent)data;
// boolean sameProject = d2.getWorkspaceRelativePath() != null
// && d2.getWorkspaceRelativePath().segment(0)
// .equals(rootComponent.getProject().getName());
// return !(sameProject && isPhysicallyAdded(d2));
// }
protected void addDoubleClickListener() {
availableComponentsViewer.setColumnProperties(new String[] {
DEPLOY_PATH_PROPERTY, SOURCE_PROPERTY });
CellEditor[] editors = new CellEditor[] {
new TextCellEditor(availableComponentsViewer.getTable()),
new TextCellEditor()};
availableComponentsViewer.setCellEditors(editors);
availableComponentsViewer
.setCellModifier(new RuntimePathCellModifier());
}
protected void addSelectionListener() {
availableComponentsViewer.addSelectionChangedListener(
new ISelectionChangedListener(){
public void selectionChanged(SelectionChangedEvent event) {
viewerSelectionChanged();
}
});
}
protected void viewerSelectionChanged() {
editReferenceButton.setEnabled(hasEditWizardPage(getSelectedObject()));
removeButton.setEnabled(getSelectedObject() != null);// && canEdit(getSelectedObject()));
}
protected boolean hasEditWizardPage(Object o) {
if( o == null || !(o instanceof IVirtualComponent))
return false;
WizardFragment wf = NewReferenceWizard.getFirstEditingFragment((IVirtualComponent)o);
return wf != null;
}
protected Object getSelectedObject() {
IStructuredSelection sel = (IStructuredSelection)availableComponentsViewer.getSelection();
return sel.getFirstElement();
}
private class RuntimePathCellModifier implements ICellModifier {
public boolean canModify(Object element, String property) {
if( property.equals(DEPLOY_PATH_PROPERTY)) {
// if (element instanceof VirtualArchiveComponent) {
// try {
// return canEdit(element);
// } catch (IllegalArgumentException iae) {
// }
// }
return true;
}
return false;
}
public Object getValue(Object element, String property) {
Object data = element; //((TableItem)element).getData();
if( data instanceof IVirtualComponent ) {
return objectToRuntimePath.get(element) == null ? new Path("/") //$NON-NLS-1$
.toString() : objectToRuntimePath.get(element);
} else if( data instanceof ComponentResourceProxy) {
return ((ComponentResourceProxy)data).runtimePath.toString();
}
return new Path("/"); //$NON-NLS-1$
}
public void modify(Object element, String property, Object value) {
if (property.equals(DEPLOY_PATH_PROPERTY)) {
TableItem item = (TableItem) element;
if( item.getData() instanceof IVirtualComponent) {
objectToRuntimePath.put((IVirtualComponent)item.getData(), (String) value);
} else if( item.getData() instanceof ComponentResourceProxy) {
ComponentResourceProxy c = ((ComponentResourceProxy)item.getData());
c.runtimePath = new Path((String)value);
resourceMappingsChanged = true;
}
refresh();
}
}
}
public void handleEvent(Event event) {
// if( event.widget == addMappingButton)
// handleAddMappingButton();
// else
if( event.widget == addReferenceButton)
handleAddReferenceButton();
else if( event.widget == editReferenceButton)
handleEditReferenceButton();
else if( event.widget == removeButton )
handleRemoveSelectedButton();
}
// protected void handleAddMappingButton() {
// AddFolderDialog afd = new AddFolderDialog(addMappingButton.getShell(), project);
// if( afd.open() == Window.OK) {
// IContainer c = afd.getSelected();
// if( c != null ) {
// IPath p = c.getProjectRelativePath();
// ComponentResourceProxy proxy = new ComponentResourceProxy(p, new Path("/")); //$NON-NLS-1$
// resourceMappings.add(proxy);
// refresh();
// }
// }
// }
protected void handleAddReferenceButton() {
showReferenceWizard(false);
}
protected void handleEditReferenceButton() {
showReferenceWizard(true);
}
protected ReferenceExtension[] filterReferenceTypes(ReferenceExtension[] defaults) {
return defaults;
}
protected void showReferenceWizard(boolean editing) {
ReferenceExtension[] extensions =
DependencyPageExtensionManager.getManager().getExposedReferenceExtensions();
extensions = filterReferenceTypes(extensions);
NewReferenceWizard wizard = new NewReferenceWizard(extensions);
// fill the task model
wizard.getTaskModel().putObject(IReferenceWizardConstants.PROJECT, project);
wizard.getTaskModel().putObject(IReferenceWizardConstants.ROOT_COMPONENT, rootComponent);
wizard.getTaskModel().putObject(IReferenceWizardConstants.MODULEHANDLER, getModuleHandler());
IVirtualComponent selected = null;
if( editing ) {
Object o = ((IStructuredSelection)availableComponentsViewer.getSelection()).getFirstElement();
if( o instanceof IVirtualComponent ) {
selected = (IVirtualComponent)o;
wizard.getTaskModel().putObject(IReferenceWizardConstants.COMPONENT, selected);
wizard.getTaskModel().putObject(IReferenceWizardConstants.COMPONENT_PATH, objectToRuntimePath.get(selected));
}
}
WizardDialog wd = new WizardDialog(addReferenceButton.getShell(), wizard);
if( wd.open() != Window.CANCEL) {
if( editing && selected != null) {
// remove old
objectToRuntimePath.remove(selected);
consumedReferences.remove(selected);
}
if( wizard.getTaskModel().getObject(IReferenceWizardConstants.FOLDER_MAPPING) != null )
handleAddFolderMapping(wizard);
else
handleAddNewReference(wizard);
refresh();
}
}
protected void handleAddFolderMapping(TaskWizard wizard) {
Object o = wizard.getTaskModel().getObject(IReferenceWizardConstants.FOLDER_MAPPING);
if( o != null && o instanceof ComponentResourceProxy ) {
ComponentResourceProxy proxy = (ComponentResourceProxy)o;
resourceMappings.add(proxy);
}
}
protected void handleAddNewReference(TaskWizard wizard) {
Object c1 = wizard.getTaskModel().getObject(IReferenceWizardConstants.COMPONENT);
Object p1 = wizard.getTaskModel().getObject(IReferenceWizardConstants.COMPONENT_PATH);
DependencyType type = (DependencyType)wizard.getTaskModel().getObject(IReferenceWizardConstants.DEPENDENCY_TYPE);
boolean consumed = type == null ? false : type.equals(DependencyType.CONSUMES_LITERAL);
IVirtualComponent[] compArr = c1 instanceof IVirtualComponent ?
new IVirtualComponent[] { (IVirtualComponent)c1 } :
(IVirtualComponent[])c1;
String[] pathArr = p1 instanceof String ?
new String[] { (String)p1 } :
(String[])p1;
for( int i = 0; i < compArr.length; i++ ) {
objectToRuntimePath.put(compArr[i],
getRuntimePath(compArr[i], pathArr[i]));
if( consumed )
consumedReferences.add(compArr[i]);
}
}
/**
* Subclasses are encouraged to override this method if
* they have some specific place (webinf/lib etc) where certain
* types of references should default to.
*
* If the subclass does not understand or know about the
* this component type, or if it has no customizations to perform,
* it should return the provided wizardPath unchanged
*
* @param addedComp The component being added as a reference
* @param addedPath The path that the wizard suggests as the path
* @return The runtime path that should be added to the properties page
*/
protected String getRuntimePath(IVirtualComponent addedComp, String wizardPath) {
return wizardPath;
}
protected void handleRemoveSelectedButton() {
ISelection sel = availableComponentsViewer.getSelection();
if( sel instanceof IStructuredSelection ) {
IStructuredSelection sel2 = (IStructuredSelection)sel;
Object[] selectedStuff = sel2.toArray();
for( int i = 0; i < selectedStuff.length; i++) {
Object o = selectedStuff[i];
if( o instanceof IVirtualComponent)
objectToRuntimePath.remove(o);
else if( o instanceof ComponentResourceProxy)
resourceMappings.remove(o);
}
refresh();
}
}
public TableViewer createAvailableComponentsViewer(Composite parent) {
int flags = SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI;
Table table = new Table(parent, flags);
TableViewer tempViewer = new TableViewer(table);
// set up table layout
TableLayout tableLayout = new org.eclipse.jface.viewers.TableLayout();
tableLayout.addColumnData(new ColumnWeightData(400, true));
tableLayout.addColumnData(new ColumnWeightData(500, true));
table.setLayout(tableLayout);
table.setHeaderVisible(true);
table.setLinesVisible(true);
tempViewer.setSorter(null);
TableColumn bndColumn = new TableColumn(table, SWT.NONE, 0);
bndColumn.setText(Messages.DeployPathColumn);
bndColumn.setResizable(true);
TableColumn projectColumn = new TableColumn(table, SWT.NONE, 1);
projectColumn.setText(Messages.SourceColumn);
projectColumn.setResizable(true);
tableLayout.layout(table, true);
return tempViewer;
}
// protected boolean isPhysicallyAdded(VirtualArchiveComponent component) {
// try {
// component.getProjectRelativePath();
// return true;
// } catch (IllegalArgumentException e) {
// return false;
// }
// }
/**
* This should only be called on changes, such as adding a project
* reference, adding a lib reference etc.
*
* It will reset the input, manually re-add missing elements, and do other
* tasks
*/
public void refresh() {
resetTableUI();
if (!hasInitialized) {
initialize();
resetTableUI();
}
}
protected void resetTableUI() {
IWorkspaceRoot input = ResourcesPlugin.getWorkspace().getRoot();
availableComponentsViewer.setInput(input);
GridData data = new GridData(GridData.FILL_BOTH);
int numlines = Math.min(10, availableComponentsViewer.getTable()
.getItemCount());
data.heightHint = availableComponentsViewer.getTable().getItemHeight()
* numlines;
availableComponentsViewer.getTable().setLayoutData(data);
GridData btndata = new GridData(GridData.HORIZONTAL_ALIGN_FILL
| GridData.VERTICAL_ALIGN_BEGINNING);
buttonColumn.setLayoutData(btndata);
}
protected void initialize() {
Map<String, Object> options = new HashMap<String, Object>();
options.put(IVirtualComponent.REQUESTED_REFERENCE_TYPE, IVirtualComponent.DISPLAYABLE_REFERENCES);
IVirtualReference[] refs = rootComponent.getReferences(options);
IVirtualComponent comp;
for( int i = 0; i < refs.length; i++ ) {
comp = refs[i].getReferencedComponent();
String archiveName = refs[i].getDependencyType() == DependencyType.CONSUMES ? null : refs[i].getArchiveName();
String val = (archiveName != null) ? refs[i].getRuntimePath().append(archiveName).toString() : refs[i].getRuntimePath().toString();
objectToRuntimePath.put(comp, val);
oldComponentToRuntimePath.put(comp, val);
if( refs[i].getDependencyType() == DependencyType.CONSUMES)
consumedReferences.add(comp);
}
ComponentResource[] allMappings = findAllMappings();
for( int i = 0; i < allMappings.length; i++ ) {
resourceMappings.add(new ComponentResourceProxy(
allMappings[i].getSourcePath(), allMappings[i].getRuntimePath()
));
}
if(editReferenceButton != null)
editReferenceButton.setEnabled(false);
if(removeButton != null)
removeButton.setEnabled(false);
hasInitialized = true;
}
protected ComponentResource[] findAllMappings() {
StructureEdit structureEdit = null;
try {
structureEdit = StructureEdit.getStructureEditForRead(project);
WorkbenchComponent component = structureEdit.getComponent();
Object[] arr = component.getResources().toArray();
ComponentResource[] result = new ComponentResource[arr.length];
for( int i = 0; i < arr.length; i++ )
result[i] = (ComponentResource)arr[i];
return result;
} catch(Exception e) {
} finally {
structureEdit.dispose();
}
return new ComponentResource[]{};
}
public static class ComponentResourceProxy {
public IPath source, runtimePath;
public ComponentResourceProxy(IPath source, IPath runtimePath) {
this.source = source;
this.runtimePath = runtimePath;
}
}
/*
* Clean-up methods are below. These include performCancel, performDefaults,
* performOK, and any other methods that are called *only* by this one.
*/
public void setVisible(boolean visible) {
}
public void performDefaults() {
}
public boolean performCancel() {
return true;
}
public void dispose() {
Table table = null;
if (availableComponentsViewer != null) {
table = availableComponentsViewer.getTable();
}
// if (table == null || tableListener == null)
// return;
// table.removeListener(SWT.Dispose, tableListener);
// table.removeListener(SWT.KeyDown, tableListener);
// table.removeListener(SWT.MouseMove, tableListener);
// table.removeListener(SWT.MouseHover, tableListener);
}
/*
* This is where the OK work goes. Lots of it. Watch your head.
* xiao xin
*/
protected boolean preHandleChanges(IProgressMonitor monitor) {
return true;
}
protected boolean postHandleChanges(IProgressMonitor monitor) {
return true;
}
public boolean performOk() {
boolean result = true;
result &= saveResourceChanges();
result &= saveReferenceChanges();
return result;
}
protected boolean saveResourceChanges() {
removeAllResourceMappings();
addNewResourceMappings();
return true;
}
protected boolean addNewResourceMappings() {
ComponentResourceProxy[] proxies = resourceMappings.toArray(new ComponentResourceProxy[resourceMappings.size()]);
IVirtualFolder rootFolder = rootComponent.getRootFolder();
for( int i = 0; i < proxies.length; i++ ) {
try {
rootFolder.getFolder(proxies[i].runtimePath).createLink(proxies[i].source, 0, null);
} catch( CoreException ce ) {
}
}
resourceMappingsChanged = false;
return true;
}
protected boolean removeAllResourceMappings() {
StructureEdit moduleCore = null;
try {
moduleCore = StructureEdit.getStructureEditForWrite(project);
moduleCore.getComponent().getResources().clear();
}
finally {
if (moduleCore != null) {
moduleCore.saveIfNecessary(new NullProgressMonitor());
moduleCore.dispose();
}
}
return true;
}
protected boolean saveReferenceChanges() {
// Fill our delta lists
ArrayList<IVirtualComponent> added = new ArrayList<IVirtualComponent>();
ArrayList<IVirtualComponent> removed = new ArrayList<IVirtualComponent>();
ArrayList<IVirtualComponent> changed = new ArrayList<IVirtualComponent>();
Iterator<IVirtualComponent> j = oldComponentToRuntimePath.keySet().iterator();
Object key, val;
while (j.hasNext()) {
key = j.next();
val = oldComponentToRuntimePath.get(key);
if( !objectToRuntimePath.containsKey(key))
removed.add((IVirtualComponent)key);
else if (!val.equals(objectToRuntimePath.get(key)))
changed.add((IVirtualComponent)key);
}
j = objectToRuntimePath.keySet().iterator();
while (j.hasNext()) {
key = j.next();
if (!oldComponentToRuntimePath.containsKey(key))
added.add((IVirtualComponent)key);
}
NullProgressMonitor monitor = new NullProgressMonitor();
boolean subResult = preHandleChanges(monitor);
if( !subResult )
return false;
handleDeltas(removed, changed, added);
subResult &= postHandleChanges(monitor);
// Now update the variables
oldComponentToRuntimePath.clear();
ArrayList<IVirtualComponent> keys = new ArrayList<IVirtualComponent>();
keys.addAll(objectToRuntimePath.keySet());
Iterator<IVirtualComponent> i = keys.iterator();
while(i.hasNext()) {
IVirtualComponent vc = i.next();
String path = objectToRuntimePath.get(vc);
oldComponentToRuntimePath.put(vc, path);
}
return subResult;
}
// Subclass can override if it has a good way to handle changed elements
protected void handleDeltas(ArrayList<IVirtualComponent> removed,
ArrayList<IVirtualComponent> changed, ArrayList<IVirtualComponent> added) {
ArrayList<IVirtualComponent> removed2 = new ArrayList<IVirtualComponent>();
ArrayList<IVirtualComponent> added2 = new ArrayList<IVirtualComponent>();
removed2.addAll(removed);
removed2.addAll(changed);
added2.addAll(added);
added2.addAll(changed);
// meld the changed into the added / removed for less efficiency ;)
// basically we lack "change" operations and only have add / remove
handleRemoved(removed2);
handleAdded(added2);
}
protected void handleRemoved(ArrayList<IVirtualComponent> removed) {
// If it's removed it should *only* be a virtual component already
if(removed.isEmpty()) return;
final ArrayList<IVirtualComponent> components = new ArrayList<IVirtualComponent>();
Iterator<IVirtualComponent> i = removed.iterator();
IVirtualComponent o;
while(i.hasNext()) {
o = i.next();
components.add(o);
}
IWorkspaceRunnable runnable = new IWorkspaceRunnable(){
public void run(IProgressMonitor monitor) throws CoreException{
removeComponents(components);
}
};
try {
ResourcesPlugin.getWorkspace().run(runnable, new NullProgressMonitor());
} catch( CoreException e ) {
ModuleCoreUIPlugin.logError(e);
}
}
protected void removeComponents(ArrayList<IVirtualComponent> removed) {
Iterator<IVirtualComponent> i = removed.iterator();
while(i.hasNext()) {
removeOneComponent(i.next());
}
}
protected void removeOneComponent(IVirtualComponent comp) {
try {
IDataModelOperation operation = getRemoveComponentOperation(comp);
operation.execute(null, null);
} catch( ExecutionException e) {
ModuleCoreUIPlugin.logError(e);
}
}
protected IDataModelOperation getRemoveComponentOperation(IVirtualComponent component) {
String path, archiveName;
path = archiveName = null;
if( !consumedReferences.contains(component)) {
path = new Path(oldComponentToRuntimePath.get(component)).removeLastSegments(1).toString();
archiveName = new Path(oldComponentToRuntimePath.get(component)).lastSegment();
} else {
path = oldComponentToRuntimePath.get(component);
}
IDataModelProvider provider = getRemoveReferenceDataModelProvider(component);
IDataModel model = DataModelFactory.createDataModel(provider);
model.setProperty(ICreateReferenceComponentsDataModelProperties.SOURCE_COMPONENT, rootComponent);
List<IVirtualComponent> modHandlesList = (List<IVirtualComponent>) model.getProperty(ICreateReferenceComponentsDataModelProperties.TARGET_COMPONENT_LIST);
modHandlesList.add(component);
model.setProperty(ICreateReferenceComponentsDataModelProperties.TARGET_COMPONENT_LIST, modHandlesList);
model.setProperty(ICreateReferenceComponentsDataModelProperties.TARGET_COMPONENTS_DEPLOY_PATH, path);
Map<IVirtualComponent, String> uriMap = new HashMap<IVirtualComponent, String>();
uriMap.put(component, archiveName);
model.setProperty(ICreateReferenceComponentsDataModelProperties.TARGET_COMPONENTS_TO_URI_MAP, uriMap);
return model.getDefaultOperation();
}
protected IDataModelProvider getRemoveReferenceDataModelProvider(IVirtualComponent component) {
return new RemoveReferenceComponentsDataModelProvider();
}
protected void handleChanged(ArrayList<IVirtualComponent> changed) {
Iterator<IVirtualComponent> i = changed.iterator();
IVirtualComponent component;
IVirtualReference ref;
IPath p;
while(i.hasNext()) {
component = i.next();
ref = rootComponent.getReference(component.getName());
p = new Path(objectToRuntimePath.get(component));
ref.setRuntimePath(p);
}
}
protected void handleAdded(ArrayList<IVirtualComponent> added) {
final ArrayList<IVirtualComponent> components = new ArrayList<IVirtualComponent>();
Iterator<IVirtualComponent> i = added.iterator();
IVirtualComponent o;
while(i.hasNext()) {
o = i.next();
components.add(o);
}
IWorkspaceRunnable runnable = new IWorkspaceRunnable(){
public void run(IProgressMonitor monitor) throws CoreException{
addComponents(components);
}
};
try {
ResourcesPlugin.getWorkspace().run(runnable, new NullProgressMonitor());
} catch( CoreException e ) {
ModuleCoreUIPlugin.logError(e);
}
}
protected void addComponents(ArrayList<IVirtualComponent> components) throws CoreException {
Iterator<IVirtualComponent> i = components.iterator();
while(i.hasNext()) {
addOneComponent(i.next());
}
}
protected IDataModelProvider getAddReferenceDataModelProvider(IVirtualComponent component) {
return new CreateReferenceComponentsDataModelProvider();
}
protected void addOneComponent(IVirtualComponent component) throws CoreException {
String path, archiveName;
path = new Path(objectToRuntimePath.get(component)).removeLastSegments(1).toString();
archiveName = new Path(objectToRuntimePath.get(component)).lastSegment();
IDataModelProvider provider = getAddReferenceDataModelProvider(component);
IDataModel dm = DataModelFactory.createDataModel(provider);
dm.setProperty(ICreateReferenceComponentsDataModelProperties.SOURCE_COMPONENT, rootComponent);
dm.setProperty(ICreateReferenceComponentsDataModelProperties.TARGET_COMPONENT_LIST, Arrays.asList(component));
//[Bug 238264] the uri map needs to be manually set correctly
Map<IVirtualComponent, String> uriMap = new HashMap<IVirtualComponent, String>();
uriMap.put(component, archiveName);
dm.setProperty(ICreateReferenceComponentsDataModelProperties.TARGET_COMPONENTS_TO_URI_MAP, uriMap);
dm.setProperty(ICreateReferenceComponentsDataModelProperties.TARGET_COMPONENTS_DEPLOY_PATH, path);
IStatus stat = dm.validateProperty(ICreateReferenceComponentsDataModelProperties.TARGET_COMPONENT_LIST);
if (stat != OK_STATUS)
throw new CoreException(stat);
try {
dm.getDefaultOperation().execute(new NullProgressMonitor(), null);
} catch (ExecutionException e) {
ModuleCoreUIPlugin.logError(e);
}
}
public void labelProviderChanged(LabelProviderChangedEvent event) {
if(!availableComponentsViewer.getTable().isDisposed())
availableComponentsViewer.refresh(true);
}
protected IModuleHandler getModuleHandler() {
if(moduleHandler == null)
moduleHandler = new DefaultModuleHandler();
return moduleHandler;
}
// /**
// * [Bug 238264]
// * determines a unique URI mapping name for a given component
// * this is in case two components have the same name.
// *
// * @return returns a valid (none duplicate) uri mapping name for the given component\
// */
// private String getURIMappingName(IVirtualComponent archive) {
//
// //get the default uri map name for the given archive
// IPath componentPath = Path.fromOSString(archive.getName());
// String uriMapName = componentPath.lastSegment().replace(' ', '_');
//
//
// //check to be sure this uri mapping is not already in use by another reference
// boolean dupeArchiveName;
// String refedCompName;
// int lastDotIndex;
// String increment;
// IVirtualReference [] existingRefs = rootComponent.getReferences();
// for(int i=0;i<existingRefs.length;i++){
// refedCompName = existingRefs[i].getReferencedComponent().getName();
//
// //if uri mapping names of the refed component and the given archive are the same
// // find a new uri map name for the given archive
// if(existingRefs[i].getArchiveName().equals(uriMapName)){
// dupeArchiveName = true;
// //find a new uriMapName for the given component
// for(int j=1; dupeArchiveName; j++){
// lastDotIndex = uriMapName.lastIndexOf('.');
// increment = "_"+j; //$NON-NLS-1$
//
// //create the new potential name
// if(lastDotIndex != -1){
// uriMapName = uriMapName.substring(0, lastDotIndex) + increment + uriMapName.substring(lastDotIndex);
// } else {
// uriMapName = uriMapName.substring(0)+increment;
// }
//
// //determine if the new potential name is valid
// for(int k=0; k<existingRefs.length; k++) {
// dupeArchiveName = existingRefs[k].getArchiveName().equals(uriMapName);
// if(dupeArchiveName) {
// break;
// }
// }
// }
// }
// }
//
// return uriMapName;
// }
}