package org.zend.php.zendserver.deployment.ui.editors;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IMarkerDelta;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.text.IDocument;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.editors.text.TextEditor;
import org.eclipse.ui.forms.editor.FormEditor;
import org.eclipse.ui.forms.editor.FormPage;
import org.eclipse.ui.forms.editor.IFormPage;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.part.FileEditorInput;
import org.zend.php.zendserver.deployment.core.IncrementalDeploymentBuilder;
import org.zend.php.zendserver.deployment.core.descriptor.ChangeEvent;
import org.zend.php.zendserver.deployment.core.descriptor.DeploymentDescriptorPackage;
import org.zend.php.zendserver.deployment.core.descriptor.DescriptorContainerManager;
import org.zend.php.zendserver.deployment.core.descriptor.IDeploymentDescriptor;
import org.zend.php.zendserver.deployment.core.descriptor.IDescriptorChangeListener;
import org.zend.php.zendserver.deployment.core.descriptor.IDescriptorContainer;
import org.zend.php.zendserver.deployment.core.descriptor.ProjectType;
import org.zend.php.zendserver.deployment.core.internal.descriptor.Feature;
import org.zend.php.zendserver.deployment.ui.Activator;
import org.zend.php.zendserver.deployment.ui.Messages;
import org.zend.php.zendserver.deployment.ui.editors.DescriptorEditorPage.FormDecoration;
import org.zend.sdklib.mapping.MappingModelFactory;
public class DeploymentDescriptorEditor extends FormEditor implements
IResourceChangeListener {
public static final String ID = "org.zend.php.zendserver.deployment.ui.editors.DeploymentDescriptorEditor"; //$NON-NLS-1$
public static final String TOOLBAR_LOCATION_URI = "toolbar:org.zend.php.zendserver.deployment.ui.editors.DeploymentDescriptorEditor"; //$NON-NLS-1$
private TextEditor descriptorSourcePage;
private TextEditor propertiesSourcePage;
protected FormToolkit createToolkit(Display display) {
// Create a toolkit that shares colors between editors.
return new FormToolkit(Activator.getDefault().getFormColors(display));
}
protected void addPages() {
try {
addPage(new OverviewPage(this, fModel));
addPage(new DescriptorMasterDetailsPage(
this,
new DependenciesMasterDetailsProvider(fModel),
"dependencies", Messages.DeploymentDescriptorEditor_Dependencies)); //$NON-NLS-1$
FormPage automationPage = new AutomationPage(
DeploymentDescriptorEditor.this, "automation", //$NON-NLS-1$
Messages.DeploymentDescriptorEditor_Scripts);
ProjectType type = fModel.getDescriptorModel().getType();
if (type == ProjectType.APPLICATION || type == ProjectType.UNKNOWN) {
addPage(automationPage);
}
addMappingPages();
// add deployment.xml page
descriptorSourcePage = new SourcePage();
int pageIndex = addPage(descriptorSourcePage, getEditorInput());
setPageText(pageIndex, getEditorInput().getName());
initDescriptor();
} catch (PartInitException e) {
//
}
}
private IDescriptorContainer fModel;
private String iconLocation = Activator.IMAGE_DESCRIPTOR_OVERVIEW;
private FileEditorInput propertiesInput;
/**
* Creates a multi-page editor example.
*/
public DeploymentDescriptorEditor() {
super();
ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
}
/**
* The <code>MultiPageEditorPart</code> implementation of this
* <code>IWorkbenchPart</code> method disposes all nested editors.
* Subclasses may extend.
*/
public void dispose() {
ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
super.dispose();
}
/**
* Saves the multi-page editor's document.
*/
public void doSave(IProgressMonitor monitor) {
descriptorSourcePage.doSave(monitor);
if (isMappingAvailable() && propertiesSourcePage != null) {
propertiesSourcePage.doSave(monitor);
}
}
/**
* Saves the multi-page editor's document as another file. Also updates the
* control for page 0's tab, and updates this multi-page editor's input to
* correspond to the nested editor's.
*/
public void doSaveAs() {
IEditorPart editor = getEditor(0);
editor.doSaveAs();
setPageText(0, editor.getTitle());
setInput(editor.getEditorInput());
}
/*
* (non-Javadoc) Method declared on IEditorPart
*/
public void gotoMarker(IMarker marker) {
setActivePage(0);
IDE.gotoMarker(getEditor(0), marker);
}
public void init(IEditorSite site, IEditorInput editorInput)
throws PartInitException {
if (!(editorInput instanceof IFileEditorInput))
throw new PartInitException(
"Invalid Input: Must be IFileEditorInput"); //$NON-NLS-1$
IFileEditorInput fileInput = (IFileEditorInput) editorInput;
fModel = DescriptorContainerManager.getService()
.openDescriptorContainer(fileInput.getFile());
super.init(site, editorInput);
ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
setPartName(fileInput.getFile().getProject().getName());
}
private void initDescriptor() throws PartInitException {
try {
descriptorSourcePage.getDocumentProvider().connect(getEditorInput());
} catch (CoreException e) {
throw new PartInitException(new Status(IStatus.ERROR,
Activator.PLUGIN_ID, e.getMessage(), e));
}
fModel.connect(getDocument());
changeIcon(fModel.getDescriptorModel().getIconLocation());
fModel.getDescriptorModel().addListener(
new IDescriptorChangeListener() {
public void descriptorChanged(ChangeEvent event) {
if (event.target instanceof IDeploymentDescriptor) {
handleModelUpdate((IDeploymentDescriptor) event.target);
}
if (event.feature
.equals(DeploymentDescriptorPackage.PKG_TYPE)) {
if (event.newValue != null
&& !event.newValue.equals(event.oldValue)) {
handleTypeChanged((String) event.newValue);
}
}
}
});
}
private void handleTypeChanged(String value) {
int count = DeploymentDescriptorEditor.this.getPageCount();
switch (ProjectType.byName(value)) {
case APPLICATION:
if (count != 5 && count != 3) {
return;
}
getEditorSite().getShell().getDisplay().asyncExec(new Runnable() {
public void run() {
try {
FormPage automationPage = new AutomationPage(
DeploymentDescriptorEditor.this, "automation", //$NON-NLS-1$
Messages.DeploymentDescriptorEditor_Scripts);
DeploymentDescriptorEditor.this.addPage(2,
automationPage);
} catch (PartInitException e) {
Activator.log(e);
}
}
});
break;
case LIBRARY:
if (count != 6 && count != 4) {
return;
}
getEditorSite().getShell().getDisplay().asyncExec(new Runnable() {
public void run() {
DeploymentDescriptorEditor.this.removePage(2);
}
});
break;
default:
break;
}
}
private void initMapping() throws PartInitException {
IFile propsFile = (IFile) fModel.getMappingFile();
propertiesInput = new FileEditorInput(propsFile);
try {
propertiesSourcePage.getDocumentProvider().connect(
getPropertiesInput());
} catch (CoreException e) {
throw new PartInitException(new Status(IStatus.ERROR,
Activator.PLUGIN_ID, e.getMessage(), e));
}
fModel.initializeMappingModel(getPropertiesDocument());
}
protected void handleModelUpdate(final IDeploymentDescriptor descr) {
getEditorSite().getShell().getDisplay().asyncExec(new Runnable() {
public void run() {
String newIconLocation = descr.getIconLocation();
changeIcon(newIconLocation);
}
});
}
private void changeIcon(String newIconLocation) {
// if nothing has changed then keep as is
if ((newIconLocation == iconLocation)
|| (newIconLocation != null && (newIconLocation
.equals(iconLocation)))) {
return;
}
// new icon location - check if we have it in image registry
ImageRegistry reg = Activator.getDefault().getImageRegistry();
Image img = null;
if (newIconLocation != null) {
img = reg.get(newIconLocation);
}
// image is in registry, let's use new location as is
if (img != null) {
iconLocation = newIconLocation;
} else {
IFile file = null;
if (newIconLocation != null) {
try {
file = fModel.getProject().getFile(newIconLocation);
} catch (RuntimeException e) {
// ignore
}
}
if (file != null && file.exists()) {
String filePath = file.getLocation().toFile().getAbsolutePath();
try {
img = Activator.getDefault().createWorkspaceImage(filePath, 16);
} catch (SWTException ex) {
// ignore, e.g. unsupported file format exception
}
if (img != null) {
iconLocation = newIconLocation;
// reg.remove(iconLocation); // remove previous image
reg.put(iconLocation, img);
} else {
iconLocation = null;
}
} else {
iconLocation = null;
}
}
updateImage();
}
private void updateImage() {
String icon = iconLocation != null ? iconLocation : Activator.IMAGE_DESCRIPTOR_OVERVIEW;
Image img = Activator.getDefault().getImage(icon);
IFormPage page = getActivePageInstance();
if ((page != null) && (page instanceof FormPage)) {
FormPage fpage = (FormPage) page;
fpage.getManagedForm().getForm().setImage(img);
}
}
private boolean isMappingAvailable() {
return fModel.getMappingModel() != null && fModel.getMappingModel().isLoaded();
}
/*
* (non-Javadoc) Method declared on IEditorPart.
*/
public boolean isSaveAsAllowed() {
return true;
}
/**
* Calculates the contents of page 2 when the it is activated.
*/
protected void pageChange(int newPageIndex) {
super.pageChange(newPageIndex);
updateImage();
if (newPageIndex == 2) {
//
}
}
public void resourceChanged(IResourceChangeEvent event) {
IMarkerDelta[] markerDeltas = event.findMarkerDeltas(
IncrementalDeploymentBuilder.PROBLEM_MARKER, true);
if (markerDeltas.length > 0) {
refreshProblemMarkers(markerDeltas);
}
IResourceDelta delta = event.getDelta();
if (delta == null) {
return;
}
IResourceDelta[] children = delta.getAffectedChildren();
if (children != null) {
for (IResourceDelta child : children) {
if (child.getResource() == fModel.getFile().getParent()) {
IResourceDelta[] affectedChildren = child.getAffectedChildren();
if (affectedChildren == null) {
return;
}
for (IResourceDelta affectedChild : affectedChildren) {
if (affectedChild.getResource().getName().equals(MappingModelFactory.DEPLOYMENT_PROPERTIES)) {
boolean isAvailable = false;
if (fModel.getFile().getParent().findMember(
MappingModelFactory.DEPLOYMENT_PROPERTIES) != null) {
isAvailable = true;
}
if (isAvailable && !isMappingAvailable()) {
addMappingPages();
} else if (!isAvailable && isMappingAvailable()) {
removeMappingPages();
}
}
}
}
}
}
IResourceDeltaVisitor visitor = new IResourceDeltaVisitor() {
public boolean visit(IResourceDelta delta) throws CoreException {
IResource resource = delta.getResource();
IFile editorFile = fModel.getFile();
int flag = delta.getFlags();
if (resource instanceof IProject) {
// project was closed
IProject project = (IProject) resource;
if (editorFile.getProject().equals(project) && (!project.isOpen()) && ((flag & IResourceDelta.OPEN) != 0)) {
close(false);
}
} else if (resource instanceof IFile) {
// descriptor file was removed
IFile file = (IFile) resource;
if (delta.getKind() == IResourceDelta.REMOVED && editorFile.equals(file)) {
close(false);
}
}
return true;
}
};
try {
delta.accept(visitor);
} catch (CoreException e) {
// ignore
}
}
private void refreshProblemMarkers(IMarkerDelta[] markerDeltas) {
IFormPage page = getActivePageInstance();
if (page instanceof DescriptorEditorPage) {
getEditorSite().getShell().getDisplay().asyncExec(new Runnable() {
public void run() {
IFormPage page = getActivePageInstance();
((DescriptorEditorPage) page).showMarkers();
};
});
}
}
private void removeMappingPages() {
getEditorSite().getShell().getDisplay().asyncExec(new Runnable() {
public void run() {
removePage(4);
removePage(3);
try {
fModel.getMappingModel().load(null, null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
private void addMappingPages() {
try {
if (!isMappingAvailable()) {
propertiesSourcePage = new PropertiesSourcePage();
initMapping();
}
} catch (PartInitException e) {
Activator.log(e);
}
if (isMappingAvailable()) {
getEditorSite().getShell().getDisplay().asyncExec(new Runnable() {
public void run() {
try {
if (getPageCount() == 6) {
return;
}
int index = 3;
if (getPageCount() == 3) {
index--;
}
addPage(index, new DeploymentPropertiesPage(fModel,
DeploymentDescriptorEditor.this, "package", //$NON-NLS-1$
Messages.DeploymentDescriptorEditor_Package));
addPage(++index, propertiesSourcePage,
getPropertiesInput());
setPageText(index, getPropertiesInput().getName());
} catch (PartInitException e) {
Activator.log(e);
}
}
});
}
}
public IDeploymentDescriptor getModel() {
return fModel.getDescriptorModel();
}
public IDescriptorContainer getDescriptorContainer() {
return fModel;
}
public IProject getProject() {
return fModel.getProject();
}
public FileEditorInput getPropertiesInput() {
return propertiesInput;
}
public Map<Feature, FormDecoration> getDecorationsForFeatures(Collection<Feature> keyset, int index) {
if (keyset.isEmpty()) {
return Collections.emptyMap();
}
IFile file = fModel.getFile();
IMarker[] markers;
try {
markers = file.findMarkers(IncrementalDeploymentBuilder.PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
} catch (CoreException e) {
Activator.log(e);
return Collections.emptyMap();
}
Map<Integer, Feature> featureIds = new HashMap<Integer, Feature>();
for (Feature f : keyset) {
featureIds.put(f.id, f);
}
Map<Feature, FormDecoration> toShow = new HashMap<Feature, FormDecoration>();
for (IMarker marker : markers) {
int featureId = marker.getAttribute(IncrementalDeploymentBuilder.FEATURE_ID, -1);
int objNo = marker.getAttribute(IncrementalDeploymentBuilder.OBJECT_NUMBER, -1);
if ((featureId != -1) && (objNo == index)) {
Feature feature = featureIds.get(featureId);
if (feature != null) {
toShow.put(feature, markerToDecoration(marker));
}
}
}
return toShow;
}
public Map<Feature, FormDecoration> getDecorationsForFeatures(Collection<Feature> keyset) {
return getDecorationsForFeatures(keyset, -1);
}
private FormDecoration markerToDecoration(IMarker marker) {
String message = marker.getAttribute(IMarker.MESSAGE, null);
int severity = marker.getAttribute(IMarker.SEVERITY, 0);
return new FormDecoration(message, severity);
}
public IDocument getDocument() {
return descriptorSourcePage.getDocumentProvider().getDocument(getEditorInput());
}
public IDocument getPropertiesDocument() {
return propertiesSourcePage.getDocumentProvider().getDocument(propertiesInput);
}
}