// ============================================================================ // // Copyright (C) 2006-2012 Talend Inc. - www.talend.com // // This source code is available under agreement available at // %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt // // You should have received a copy of the agreement // along with this program; if not, write to Talend SA // 9 rue Pages 92150 Suresnes, France // // ============================================================================ package org.talend.designer.core.ui.editor; import java.lang.reflect.InvocationTargetException; import java.util.List; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.notify.impl.AdapterImpl; import org.eclipse.emf.common.util.EList; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.internal.compiler.util.SuffixConstants; import org.eclipse.jdt.internal.corext.refactoring.rename.JavaRenameProcessor; import org.eclipse.jdt.internal.corext.refactoring.rename.RenameCompilationUnitProcessor; import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor; import org.eclipse.jdt.ui.actions.IJavaEditorActionDefinitionIds; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.ltk.core.refactoring.CheckConditionsOperation; import org.eclipse.ltk.core.refactoring.PerformRefactoringOperation; import org.eclipse.ltk.core.refactoring.RefactoringStatus; import org.eclipse.ltk.core.refactoring.RefactoringStatusEntry; import org.eclipse.ltk.core.refactoring.participants.RenameRefactoring; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.graphics.Color; 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.IViewPart; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.part.FileEditorInput; import org.talend.commons.exception.LoginException; import org.talend.commons.exception.PersistenceException; import org.talend.commons.ui.runtime.exception.ExceptionHandler; import org.talend.commons.ui.runtime.image.ImageProvider; import org.talend.commons.utils.VersionUtils; import org.talend.core.CorePlugin; import org.talend.core.GlobalServiceRegister; import org.talend.core.model.properties.ByteArray; import org.talend.core.model.properties.FileItem; import org.talend.core.model.properties.Information; import org.talend.core.model.properties.Item; import org.talend.core.model.properties.RoutineItem; import org.talend.core.model.repository.ERepositoryObjectType; import org.talend.core.model.repository.Folder; import org.talend.core.model.repository.IRepositoryViewObject; import org.talend.core.model.repository.RepositoryManager; import org.talend.core.model.utils.DesignerColorUtils; import org.talend.core.model.utils.RepositoryManagerHelper; import org.talend.core.repository.model.ProxyRepositoryFactory; import org.talend.core.ui.ILastVersionChecker; import org.talend.core.ui.IUIRefresher; import org.talend.core.ui.branding.IBrandingService; import org.talend.designer.core.DesignerPlugin; import org.talend.designer.core.ui.action.SaveAsRoutineAction; import org.talend.designer.core.ui.action.SaveAsSQLPatternAction; import org.talend.designer.core.ui.views.problems.Problems; import org.talend.repository.RepositoryWorkUnit; import org.talend.repository.editor.RepositoryEditorInput; import org.talend.repository.model.IProxyRepositoryFactory; import org.talend.repository.model.IRepositoryService; import org.talend.repository.model.RepositoryNode; import org.talend.repository.ui.views.IJobSettingsView; import org.talend.repository.ui.views.IRepositoryView; /** * Stand alone Perl editor.<br/> * */ public class StandAloneTalendJavaEditor extends CompilationUnitEditor implements IUIRefresher, ILastVersionChecker { public static final String ID = "org.talend.designer.core.ui.editor.StandAloneTalendJavaEditor"; //$NON-NLS-1$ private RepositoryEditorInput rEditorInput; private Boolean isEditable = true; private Color bgColorForReadOnlyItem; private Color bgColorForEditabeItem; /** * DOC smallet Comment method "getRepositoryFactory". */ private IProxyRepositoryFactory getRepositoryFactory() { return DesignerPlugin.getDefault().getRepositoryService().getProxyRepositoryFactory(); } @Override public boolean isSaveAsAllowed() { IProxyRepositoryFactory factory = ProxyRepositoryFactory.getInstance(); if (factory.isUserReadOnlyOnCurrentProject()) { return false; } return getRepositoryFactory().getStatus(item).isEditable(); } @Override public boolean isEditable() { if (!getRepositoryFactory().getStatus(item).isEditable()) { getSourceViewer().getTextWidget().setDragDetect(false); isEditable = false; } return !rEditorInput.isReadOnly() && getRepositoryFactory().getStatus(item).isEditable() && isLastVersion(item); } @Override public void doSetInput(IEditorInput input) throws CoreException { // Lock the process : IRepositoryService service = DesignerPlugin.getDefault().getRepositoryService(); IProxyRepositoryFactory repFactory = service.getProxyRepositoryFactory(); if (input instanceof RepositoryEditorInput) { rEditorInput = (RepositoryEditorInput) input; } else { FileEditorInput fileInput = (FileEditorInput) input; rEditorInput = new RepositoryEditorInput(fileInput.getFile(), rEditorInput.getItem()); } if (rEditorInput.getRepositoryNode() == null) { rEditorInput.setRepositoryNode(null); // retrieve node } try { // see bug 1321 item = (FileItem) rEditorInput.getItem(); if (!rEditorInput.isReadOnly()) { if (getRepositoryFactory().getStatus(item).isPotentiallyEditable()) { item.getProperty().eAdapters().add(dirtyListener); repFactory.lock(item); } } else { rEditorInput.getFile().setReadOnly(true); } } catch (Exception e) { ExceptionHandler.process(e); } rEditorInput.getFile().refreshLocal(IResource.DEPTH_ONE, null); super.doSetInput(rEditorInput); setName(); } private void setName() { IRepositoryView repoView = RepositoryManagerHelper.findRepositoryView(); if (repoView != null) { RepositoryNode repositoryNode = rEditorInput.getRepositoryNode(); if (repositoryNode != null) { setTitleImage(getTitleImage()); setPartName(getTitleText(repositoryNode.getObject())); } } } private String getTitleText(IRepositoryViewObject object) { StringBuffer string = new StringBuffer(); string.append(object.getLabel()); IBrandingService brandingService = (IBrandingService) GlobalServiceRegister.getDefault().getService( IBrandingService.class); boolean allowVerchange = brandingService.getBrandingConfiguration().isAllowChengeVersion(); if (!(object instanceof Folder) && allowVerchange) { string.append(" " + object.getVersion()); //$NON-NLS-1$ } // nodes in the recycle bin if (object.isDeleted()) { String oldPath = object.getPath(); string.append(" (" + oldPath + ")"); //$NON-NLS-1$ //$NON-NLS-2$ } return string.toString(); } /* * (non-Javadoc) * * @see org.eclipse.ui.part.WorkbenchPart#getTitleImage() */ @Override public Image getTitleImage() { if (item != null) { IRepositoryView viewPart = RepositoryManagerHelper.findRepositoryView(); if (viewPart != null) { RepositoryNode repositoryNode = rEditorInput.getRepositoryNode(); if (repositoryNode != null) { return ImageProvider.getImage(repositoryNode.getIcon()); } } } return super.getTitleImage(); } /* * (non-Javadoc) * * @see org.eclipse.ui.part.WorkbenchPart#getPartName() */ @Override public String getPartName() { if (item != null) { IRepositoryView viewPart = RepositoryManagerHelper.findRepositoryView(); if (viewPart != null) { RepositoryNode repositoryNode = rEditorInput.getRepositoryNode(); return getTitleText(repositoryNode.getObject()); } } return super.getPartName(); } @Override public void dispose() { // remove the Runtines .java file in the .Java Project. // try { // rEditorInput.getFile().delete(true, null); // } catch (CoreException e1) { // RuntimeExceptionHandler.process(e1); // } super.dispose(); // Unlock the process : IRepositoryService service = DesignerPlugin.getDefault().getRepositoryService(); IProxyRepositoryFactory repFactory = service.getProxyRepositoryFactory(); try { item.getProperty().eAdapters().remove(dirtyListener); repFactory.unlock(item); } catch (PersistenceException e) { // e.printStackTrace(); ExceptionHandler.process(e); } catch (LoginException e) { ExceptionHandler.process(e); } // RepositoryNode repositoryNode = rEditorInput.getRepositoryNode(); // if (repositoryNode != null) { // if (repFactory.getStatus(item) == ERepositoryStatus.DELETED) { // RepositoryManager.refreshDeletedNode(null); // } else { // RepositoryManager.refresh(repositoryNode.getObjectType()); // } // } if (!isEditable) { rEditorInput.getFile().setReadOnly(false); } // force clean jobsettings IWorkbenchWindow activeWorkbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (activeWorkbenchWindow != null) { IWorkbenchPage activePage = activeWorkbenchWindow.getActivePage(); if (activePage != null) { IViewPart findView = activePage.findView(IJobSettingsView.ID); if (findView != null) { IJobSettingsView jobsetting = (IJobSettingsView) findView; if (!jobsetting.isCleaned()) { jobsetting.cleanDisplay(); } } } } // dispose custom color if (bgColorForReadOnlyItem != null) { bgColorForReadOnlyItem.dispose(); } if (bgColorForEditabeItem != null) { bgColorForEditabeItem.dispose(); } } @Override public boolean isDirty() { if (!isEditable()) { return false; } return propertyIsDirty || super.isDirty(); } @Override public boolean isEditorInputReadOnly() { return !isEditable(); } @Override protected void editorSaved() { } @Override public void doSave(final IProgressMonitor monitor) { EList adapters = item.getProperty().eAdapters(); adapters.remove(dirtyListener); super.doSave(monitor); try { ByteArray byteArray = item.getContent(); byteArray.setInnerContentFromFile(((FileEditorInput) getEditorInput()).getFile()); IRepositoryService service = DesignerPlugin.getDefault().getRepositoryService(); final IProxyRepositoryFactory repFactory = service.getProxyRepositoryFactory(); try { CorePlugin.getDefault().getRunProcessService().getJavaProject().getProject() .build(IncrementalProjectBuilder.AUTO_BUILD, null); } catch (CoreException e1) { ExceptionHandler.process(e1); } // check syntax error addProblems(); String name = "Save Routine"; RepositoryWorkUnit<Object> repositoryWorkUnit = new RepositoryWorkUnit<Object>(name, this) { @Override protected void run() throws LoginException, PersistenceException { refreshJobAndSave(repFactory); } }; repFactory.executeRepositoryWorkUnit(repositoryWorkUnit); // for bug 11930: Unable to save Routines.* in db project // repFactory.save(item); // startRefreshJob(repFactory); } catch (Exception e) { // e.printStackTrace(); ExceptionHandler.process(e); } } private void refreshJobAndSave(final IProxyRepositoryFactory repFactory) { try { // cause it to update MaxInformationLevel repFactory.save(item); } catch (Exception e) { } // update image in repository RepositoryManager.refreshSavedNode(rEditorInput.getRepositoryNode()); // update editor image setTitleImage(getTitleImage()); } /** * add routine compilation errors into problems view. */ private void addProblems() { List<Information> informations = Problems.addRoutineFile(rEditorInput.getFile(), item.getProperty()); item.getProperty().getInformations().clear(); item.getProperty().getInformations().addAll(informations); Problems.refreshProblemTreeView(); } private FileItem item; private boolean propertyIsDirty; private final AdapterImpl dirtyListener = new AdapterImpl() { @Override public void notifyChanged(Notification notification) { if (notification.getEventType() != Notification.REMOVING_ADAPTER) { propertyIsDirty = true; Display.getDefault().syncExec(new Runnable() { @Override public void run() { firePropertyChange(IEditorPart.PROP_DIRTY); } }); } } }; /* * (non-Javadoc) * * @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor#getCorrespondingElement(org.eclipse.jdt.core.IJavaElement) */ @Override protected IJavaElement getCorrespondingElement(IJavaElement element) { return element; } /* * (non-Javadoc) * * @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor#getElementAt(int) */ @Override protected IJavaElement getElementAt(int offset) { return null; } /* * (non-Javadoc) * * @see org.talend.core.ui.IUIRefresher#refreshName() */ @Override public void refreshName() { ICompilationUnit unit = (ICompilationUnit) this.getInputJavaElement(); String newName = item.getProperty().getLabel(); propertyIsDirty = false; try { boolean noError = true; String newName2 = newName + SuffixConstants.SUFFIX_STRING_java; if (item instanceof RoutineItem && !unit.getElementName().equals(newName2)) { JavaRenameProcessor processor = new RenameCompilationUnitProcessor(unit); processor.setNewElementName(newName2); RenameRefactoring ref = new RenameRefactoring(processor); final PerformRefactoringOperation operation = new PerformRefactoringOperation(ref, CheckConditionsOperation.ALL_CONDITIONS); IRunnableWithProgress r = new IRunnableWithProgress() { @Override public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { Display.getDefault().asyncExec(new Runnable() { @Override public void run() { try { operation.run(monitor); } catch (CoreException e) { ExceptionHandler.process(e); } } }); } }; PlatformUI.getWorkbench().getProgressService().run(true, true, r); RefactoringStatus conditionStatus = operation.getConditionStatus(); if (conditionStatus != null && conditionStatus.hasError()) { String errorMessage = "Rename " + unit.getElementName() + " to " + newName + " has errors!"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ RefactoringStatusEntry[] entries = conditionStatus.getEntries(); for (RefactoringStatusEntry entry : entries) { errorMessage += "\n>>>" + entry.getMessage(); //$NON-NLS-1$ } MessageDialog.openError(this.getSite().getShell(), "Warning", errorMessage); //$NON-NLS-1$ noError = false; } } if (noError) { doSave(null); } setName(); } catch (Exception e) { ExceptionHandler.process(e); } } // reference:Process.isLastVersion(Item item) @Override public boolean isLastVersion(Item item) { if (item.getProperty() != null) { try { List<IRepositoryViewObject> allVersion = ProxyRepositoryFactory.getInstance().getAllVersion( item.getProperty().getId()); if (allVersion == null || allVersion.isEmpty()) { return false; } String lastVersion = VersionUtils.DEFAULT_VERSION; for (IRepositoryViewObject object : allVersion) { if (VersionUtils.compareTo(object.getVersion(), lastVersion) > 0) { lastVersion = object.getVersion(); } } if (VersionUtils.compareTo(item.getProperty().getVersion(), lastVersion) == 0) { return true; } } catch (PersistenceException e) { ExceptionHandler.process(e); } } return false; } @Override public boolean isEditorInputModifiable() { return isEditable(); } /* * (non-Javadoc) * * @see org.talend.core.ui.ILastVersionChecker#setLastVersion(java.lang.Boolean) */ @Override public void setLastVersion(Boolean lastVersion) { // not used yet } @Override protected void createActions() { super.createActions(); getAction(IJavaEditorActionDefinitionIds.SHOW_IN_BREADCRUMB).setEnabled(false); } @Override protected void initializeViewerColors(ISourceViewer viewer) { super.initializeViewerColors(viewer); StyledText styledText = viewer.getTextWidget(); if (!isEditable()) { bgColorForReadOnlyItem = new Color(styledText.getDisplay(), DesignerColorUtils.getPreferenceReadonlyRGB( DesignerColorUtils.READONLY_BACKGROUND_COLOR_NAME, DesignerColorUtils.DEFAULT_READONLY_COLOR)); styledText.setBackground(bgColorForReadOnlyItem); } else { bgColorForEditabeItem = new Color(styledText.getDisplay(), DesignerColorUtils.getPreferenceDesignerEditorRGB( DesignerColorUtils.JOBDESIGNER_EGITOR_BACKGROUND_COLOR_NAME, DesignerColorUtils.DEFAULT_EDITOR_COLOR)); styledText.setBackground(bgColorForEditabeItem); } } @Override public void doSaveAs() { ERepositoryObjectType type = this.rEditorInput.getRepositoryNode().getObject().getRepositoryObjectType(); if (type == ERepositoryObjectType.ROUTINES) { SaveAsRoutineAction saveAsAction = new SaveAsRoutineAction(this); saveAsAction.run(); } else if (type == ERepositoryObjectType.SQLPATTERNS) { SaveAsSQLPatternAction saveAsAction = new SaveAsSQLPatternAction(this); saveAsAction.run(); } } }