blob: 16fd110ec7cc7cc0859b02142cc3b9fed9b4610c [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.IContainer;
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.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
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.Display;
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.ui.PlatformUI;
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.internal.resources.VirtualArchiveComponent;
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.AddFolderDialog;
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.NewReferenceWizard;
import org.eclipse.wst.common.componentcore.ui.internal.propertypage.DependencyPageExtensionManager.ReferenceExtension;
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 {
private static final String DEPLOY_PATH_PROPERTY = new Integer(0).toString();
private 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));
ModuleAssemblyRootPage.createDescriptionComposite(composite,
getModuleAssemblyRootPageDescription());
createListGroup(composite);
refresh();
Dialog.applyDialogFont(parent);
return composite;
}
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);
fillComposite(composite);
}
public void fillComposite(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() {
addMappingButton = createPushButton(getAddFolderLabel());
addReferenceButton = createPushButton(getAddReferenceLabel());
editReferenceButton = createPushButton(getEditReferenceLabel());
removeButton = createPushButton(getRemoveSelectedLabel());
}
protected String getRemoveSelectedLabel() {
return Messages.RemoveSelected;
}
protected String getEditReferenceLabel() {
return Messages.EditReference;
}
protected String getAddReferenceLabel() {
return Messages.AddReference;
}
protected String getAddFolderLabel() {
return Messages.AddFolderElipses;
}
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);
}
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]);
}
refresh();
}
}
/**
* 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 ) {
Object o = ((IStructuredSelection)sel).getFirstElement();
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);
availableComponentsViewer = 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);
availableComponentsViewer.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 availableComponentsViewer;
}
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.IGNORE_DERIVED_REFERENCES, new Boolean(true));
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()
));
}
editReferenceButton.setEnabled(false);
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 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;
// }
}