// ============================================================================
//
// 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.update;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.gef.commands.Command;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.PlatformUI;
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.swt.dialogs.ProgressDialog;
import org.talend.core.CorePlugin;
import org.talend.core.model.components.ComponentUtilities;
import org.talend.core.model.components.IComponent;
import org.talend.core.model.context.JobContext;
import org.talend.core.model.metadata.IMetadataTable;
import org.talend.core.model.process.IElementParameter;
import org.talend.core.model.process.INode;
import org.talend.core.model.process.IProcess;
import org.talend.core.model.process.IProcess2;
import org.talend.core.model.properties.Item;
import org.talend.core.model.properties.JobletProcessItem;
import org.talend.core.model.properties.ProcessItem;
import org.talend.core.model.properties.Property;
import org.talend.core.model.repository.IRepositoryViewObject;
import org.talend.core.model.repository.RepositoryObject;
import org.talend.core.model.update.RepositoryUpdateManager;
import org.talend.core.model.update.UpdateResult;
import org.talend.core.model.update.UpdatesConstants;
import org.talend.core.repository.model.ProxyRepositoryFactory;
import org.talend.designer.core.DesignerPlugin;
import org.talend.designer.core.IDesignerCoreService;
import org.talend.designer.core.i18n.Messages;
import org.talend.designer.core.model.utils.emf.talendfile.ProcessType;
import org.talend.designer.core.ui.AbstractMultiPageTalendEditor;
import org.talend.designer.core.ui.editor.AbstractTalendEditor;
import org.talend.designer.core.ui.editor.process.Process;
import org.talend.designer.core.ui.editor.update.cmd.UpdateContextParameterCommand;
import org.talend.designer.core.ui.editor.update.cmd.UpdateJobletNodeCommand;
import org.talend.designer.core.ui.editor.update.cmd.UpdateMainParameterCommand;
import org.talend.designer.core.ui.editor.update.cmd.UpdateNodeParameterCommand;
import org.talend.designer.core.ui.views.contexts.Contexts;
import org.talend.designer.core.ui.views.jobsettings.JobSettings;
import org.talend.designer.core.ui.views.properties.ComponentSettings;
import org.talend.designer.joblet.model.JobletProcess;
import org.talend.repository.RepositoryPlugin;
import org.talend.repository.RepositoryWorkUnit;
import org.talend.repository.model.ERepositoryStatus;
import org.talend.repository.model.IProxyRepositoryFactory;
/**
* ggu class global comment. Detailled comment
*/
public final class UpdateManagerUtils {
/**
*
* used for get repository id and child name, such as "xxxxxxxxxxx - metadata".
*/
public static String[] getSourceIdAndChildName(final String idAndName) {
if (idAndName == null) {
return null;
}
String[] result = idAndName.split(UpdatesConstants.SEGMENT_LINE);
if (result.length == 2) {
return result;
}
return null;
}
public static IComponent getComponent(Process process, final String name) {
if (name != null) {
AbstractMultiPageTalendEditor editor = (AbstractMultiPageTalendEditor) process.getEditor();
if (editor != null) {
AbstractTalendEditor talendEditor = editor.getTalendEditor();
if (talendEditor != null) {
return talendEditor.getComponent(name);
}
}
}
return null;
}
/**
* qzhang Comment method "getNewOutputTableForConnection".
*
* @param newOutputTableList
* @param attachedConnector
* @return
*/
public static IMetadataTable getNewOutputTableForConnection(List<IMetadataTable> newOutputTableList, String tableName) {
for (IMetadataTable metadataTable : newOutputTableList) {
if (tableName != null && tableName.equals(metadataTable.getTableName())
|| tableName.equals(metadataTable.getTableName())) {
return metadataTable;
}
}
return null;
}
/**
* qzhang Comment method "getNewInputTableForConnection".
*
* @param newInputTableList
* @param connector
*
* @return
*/
public static IMetadataTable getNewInputTableForConnection(List<IMetadataTable> newInputTableList, String connector) {
for (IMetadataTable metadataTable : newInputTableList) {
if (connector != null
&& (connector.equals(metadataTable.getAttachedConnector()) || connector.equals(metadataTable.getTableName()))) {
return metadataTable;
}
}
return null;
}
/**
* qzhang Comment method "getElemParam".
*
* @param elemParams
* @param string
*
* @return
*/
public static IElementParameter getElemParam(List<IElementParameter> elemParams, String string) {
for (IElementParameter elementParameter : elemParams) {
if (string != null && string.equals(elementParameter.getContext())) {
return elementParameter;
}
}
return null;
}
public static String addBrackets(String value) {
if (value == null || UpdatesConstants.EMPTY.equals(value.trim())) {
return UpdatesConstants.EMPTY;
}
return UpdatesConstants.SPACE + UpdatesConstants.LEFT_BRACKETS + value + UpdatesConstants.RIGHT_BRACKETS;
}
public static List<IProcess2> getOpenedProcess() {
IEditorReference[] reference = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getEditorReferences();
if (reference != null) {
List<IProcess2> processes = RepositoryPlugin.getDefault().getDesignerCoreService().getOpenedProcess(reference);
if (processes != null) {
return processes;
}
}
return Collections.emptyList();
}
public static boolean executeUpdates(final List<UpdateResult> results) {
return executeUpdates(results, false);
}
@SuppressWarnings("unchecked")//$NON-NLS-1$
public static boolean executeUpdates(final List<UpdateResult> results, final IProcess2 currentProcess) {
RepositoryWorkUnit<Boolean> repositoryWorkUnit = new RepositoryWorkUnit<Boolean>(
Messages.getString("UpdateManagerUtils.updateMOfification")) { //$NON-NLS-1$
@Override
protected void run() throws LoginException, PersistenceException {
result = doExecuteUpdates(results, currentProcess);
}
};
repositoryWorkUnit.setAvoidUnloadResources(true);
ProxyRepositoryFactory.getInstance().executeRepositoryWorkUnit(repositoryWorkUnit);
return repositoryWorkUnit.getResult();
}
@SuppressWarnings("unchecked")//$NON-NLS-1$
public static boolean executeUpdates(final List<UpdateResult> results, final boolean onlySimpleShow) {
RepositoryWorkUnit<Boolean> repositoryWorkUnit = new RepositoryWorkUnit<Boolean>(
Messages.getString("UpdateManagerUtils.updateMOfification")) { //$NON-NLS-1$
@Override
protected void run() throws LoginException, PersistenceException {
result = doExecuteUpdates(results, onlySimpleShow);
}
};
repositoryWorkUnit.setAvoidUnloadResources(true);
ProxyRepositoryFactory.getInstance().executeRepositoryWorkUnit(repositoryWorkUnit);
return repositoryWorkUnit.getResult();
}
private static boolean doExecuteUpdates(final List<UpdateResult> results, boolean onlySimpleShow) {
if (results == null || results.isEmpty()) {
return false;
}
try {
// changed by hqzhang, Display.getCurrent().getActiveShell() may cause studio freeze
UpdateDetectionDialog checkDialog = new UpdateDetectionDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow()
.getShell(), results, onlySimpleShow);
if (checkDialog.open() == IDialogConstants.OK_ID) {
// final List<Object> selectResult = Arrays.asList(checkDialog.getResult());
ProgressDialog progress = new ProgressDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell()) {
@Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
monitor.setCanceled(false);
int size = (results.size() * 2 + 1) * UpdatesConstants.SCALE;
monitor.beginTask(Messages.getString("UpdateManagerUtils.Update"), size); //$NON-NLS-1$
ProxyRepositoryFactory factory = ProxyRepositoryFactory.getInstance();
IRepositoryViewObject previousObj = null;
for (UpdateResult result : results) {
// several results may keep the same objectId , they are from the same process . So no need
// unload each time.
IRepositoryViewObject currentObj = null;
String currentId = result.getObjectId();
if (result.getJob() == null && previousObj != null && previousObj.getId().equals(currentId)) {
currentObj = previousObj;
} else if (previousObj instanceof RepositoryObject) {
if (!ERepositoryStatus.LOCK_BY_USER
.equals(factory.getStatus(previousObj.getProperty().getItem()))) {
((RepositoryObject) previousObj).unload();
previousObj = null;
}
}
if (result.getJob() == null) {
if (currentObj == null && currentId != null) {
boolean checkOnlyLastVersion = Boolean.parseBoolean(DesignerPlugin.getDefault()
.getPreferenceStore().getString("checkOnlyLastVersion")); //$NON-NLS-1$
try {
if (checkOnlyLastVersion || result.getObjectVersion() == null) {
currentObj = factory.getLastVersion(currentId);
} else {
List<IRepositoryViewObject> allVersion = factory.getAllVersion(currentId);
for (IRepositoryViewObject obj : allVersion) {
if (obj.getVersion().equals(result.getObjectVersion())) {
currentObj = obj;
}
}
}
} catch (PersistenceException e) {
ExceptionHandler.process(e);
}
}
if (currentObj != null) {
previousObj = currentObj;
Item item = currentObj.getProperty().getItem();
IProcess process = null;
IDesignerCoreService designerCoreService = CorePlugin.getDefault().getDesignerCoreService();
if (item instanceof ProcessItem) {
process = designerCoreService.getProcessFromProcessItem((ProcessItem) item);
} else if (item instanceof JobletProcessItem) {
process = designerCoreService.getProcessFromJobletProcessItem((JobletProcessItem) item);
}
result.setJob(process);
// node stored in result set is not the same instance as in process after we
// load again the closed process, so need to find the corresponding node in process
if (process != null && result.getUpdateObject() instanceof INode) {
INode toUpdate = (INode) result.getUpdateObject();
for (INode node : process.getGraphicalNodes()) {
if (node.getLabel().equals(toUpdate.getLabel())) {
result.setUpdateObject(node);
}
}
}
}
}
// execute
executeUpdate(result, monitor);
if (result.getObjectId() != null) {
result.setJob(null);
}
}
// update joblet reference
upadateJobletReferenceInfor();
// refresh
refreshRelatedViewers(results);
// hyWang add method checkandRefreshProcess for bug7248
checkandRefreshProcess(results);
monitor.worked(1 * UpdatesConstants.SCALE);
monitor.done();
}
};
try {
progress.executeProcess();
} catch (InvocationTargetException e) {
ExceptionHandler.process(e);
//
} catch (InterruptedException e) {
ExceptionHandler.process(e);
//
}
return !results.isEmpty();
}
} finally {
results.clear();
}
return false;
}
private static boolean doExecuteUpdates(final List<UpdateResult> results, final IProcess2 currentProcess) {
if (results == null || results.isEmpty()) {
return false;
}
try {
// UpdateDetectionDialog checkDialog = new UpdateDetectionDialog(Display.getCurrent().getActiveShell(),
// results,
// onlySimpleShow);
// if (checkDialog.open() == IDialogConstants.OK_ID) {
// final List<Object> selectResult = Arrays.asList(checkDialog.getResult());
ProgressDialog progress = new ProgressDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell()) {
@Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
monitor.setCanceled(false);
int size = (results.size() * 2 + 1) * UpdatesConstants.SCALE;
monitor.beginTask(Messages.getString("UpdateManagerUtils.Update"), size); //$NON-NLS-1$
ProxyRepositoryFactory factory = ProxyRepositoryFactory.getInstance();
IRepositoryViewObject previousObj = null;
for (UpdateResult result : results) {
// several results may keep the same objectId , they are from the same process . So no need
// unload each time.
IRepositoryViewObject currentObj = null;
String currentId = result.getObjectId();
if (result.getJob() == null && previousObj != null && previousObj.getId().equals(currentId)) {
currentObj = previousObj;
} else if (previousObj instanceof RepositoryObject) {
if (!ERepositoryStatus.LOCK_BY_USER.equals(factory.getStatus(previousObj.getProperty().getItem()))) {
((RepositoryObject) previousObj).unload();
previousObj = null;
}
}
if (result.getJob() == null) {
if (currentObj == null && currentId != null) {
boolean checkOnlyLastVersion = Boolean.parseBoolean(DesignerPlugin.getDefault()
.getPreferenceStore().getString("checkOnlyLastVersion")); //$NON-NLS-1$
try {
if (checkOnlyLastVersion || result.getObjectVersion() == null) {
currentObj = factory.getLastVersion(currentId);
} else {
List<IRepositoryViewObject> allVersion = factory.getAllVersion(currentId);
for (IRepositoryViewObject obj : allVersion) {
if (obj.getVersion().equals(result.getObjectVersion())) {
currentObj = obj;
}
}
}
} catch (PersistenceException e) {
ExceptionHandler.process(e);
}
}
if (currentObj != null) {
previousObj = currentObj;
Item item = currentObj.getProperty().getItem();
IProcess process = null;
IDesignerCoreService designerCoreService = CorePlugin.getDefault().getDesignerCoreService();
if (item instanceof ProcessItem) {
process = designerCoreService.getProcessFromProcessItem((ProcessItem) item);
} else if (item instanceof JobletProcessItem) {
process = designerCoreService.getProcessFromJobletProcessItem((JobletProcessItem) item);
}
result.setJob(process);
// node stored in result set is not the same instance as in process after we
// load again the closed process, so need to find the corresponding node in process
if (process != null && result.getUpdateObject() instanceof INode) {
INode toUpdate = (INode) result.getUpdateObject();
for (INode node : process.getGraphicalNodes()) {
if (node.getLabel().equals(toUpdate.getLabel())) {
result.setUpdateObject(node);
}
}
}
}
}
// execute
executeUpdate(result, monitor);
if (result.getObjectId() != null) {
result.setJob(null);
}
}
// update joblet reference
upadateJobletReferenceInfor();
// refresh
refreshRelatedViewers(results);
// hyWang add method checkandRefreshProcess for bug7248
checkandRefreshProcess(results);
monitor.worked(1 * UpdatesConstants.SCALE);
monitor.done();
}
};
try {
progress.executeProcess();
} catch (InvocationTargetException e) {
ExceptionHandler.process(e);
//
} catch (InterruptedException e) {
ExceptionHandler.process(e);
//
}
return !results.isEmpty();
// }
} finally {
results.clear();
}
}
/**
*
* ggu Comment method "refreshViewers".
*/
@SuppressWarnings("unchecked")//$NON-NLS-1$
private static void refreshRelatedViewers(List results) {
boolean context = false;
boolean jobSetting = false;
boolean componentSettings = false;
boolean palette = false;
for (UpdateResult result : (List<UpdateResult>) results) {
switch (result.getUpdateType()) {
case CONTEXT:
case JOBLET_CONTEXT:
context = true;
break;
case JOB_PROPERTY_EXTRA:
case JOB_PROPERTY_STATS_LOGS:
case JOB_PROPERTY_HEADERFOOTER:
jobSetting = true;
break;
case NODE_PROPERTY:
case NODE_QUERY:
case NODE_SCHEMA:
componentSettings = true;
break;
case RELOAD:
case JOBLET_RENAMED:
case JOBLET_SCHEMA:
palette = true;
break;
default:
break;
}
}
if (context) {
Contexts.switchToCurContextsView();
}
if (jobSetting) {
JobSettings.switchToCurJobSettingsView();
}
if (componentSettings) {
ComponentSettings.switchToCurComponentSettingsView();
}
if (palette) {
ComponentUtilities.updatePalette();
}
}
private static void saveModifiedItem(UpdateResult updateResult) {
// save
IProxyRepositoryFactory factory = CorePlugin.getDefault().getProxyRepositoryFactory();
try {
if (updateResult.getJob() instanceof IProcess2) {
IProcess2 process2 = (IProcess2) updateResult.getJob();
Property property = factory.getUptodateProperty(process2.getProperty());
if (property != null) {
process2.setProperty(property);
}
ProcessType processType = process2.saveXmlFile();
Item item = process2.getProperty().getItem();
if (item instanceof JobletProcessItem) {
((JobletProcessItem) item).setJobletProcess((JobletProcess) processType);
} else {
((ProcessItem) item).setProcess(processType);
}
factory.save(item);
}
} catch (PersistenceException e) {
ExceptionHandler.process(e);
} catch (IOException e) {
ExceptionHandler.process(e);
}
}
private static void executeUpdate(UpdateResult result, IProgressMonitor monitor) {
if (result.isReadOnlyProcess()) {
return;
}
// update
Command command = null;
switch (result.getUpdateType()) {
case NODE_PROPERTY:
case NODE_SCHEMA:
case NODE_QUERY:
case NODE_SAP_IDOC:
case NODE_SAP_FUNCTION:
case NODE_VALIDATION_RULE:
command = new UpdateNodeParameterCommand(result);
break;
case JOB_PROPERTY_EXTRA:
case JOB_PROPERTY_STATS_LOGS:
case JOB_PROPERTY_HEADERFOOTER:
command = new UpdateMainParameterCommand(result);
break;
case CONTEXT:
command = executeContextUpdates(result);
break;
case CONTEXT_GROUP:
command = executeContextGroupUpdates(result);
break;
case JOBLET_RENAMED:
case JOBLET_SCHEMA:
case RELOAD:
command = executeJobletNodesUpdates(result);
break;
case JOBLET_CONTEXT:
command = new Command() { // have update in checking.
};
break;
default:
break;
}
if (command != null) {
SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, 1 * UpdatesConstants.SCALE,
SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
subMonitor.beginTask(UpdatesConstants.EMPTY, 1);
subMonitor.subTask(getResultTaskInfor(result));
//
Object job = result.getJob();
boolean executed = false;
boolean isSaveModifiedItem = false;
if (job != null) {
if (job instanceof IProcess2) {
IProcess2 process = (IProcess2) job;
process.getCommandStack().execute(command);
if (process.getEditor() != null) {
isSaveModifiedItem = true;
}
executed = true;
}
}
if (!executed) {
command.execute();
}
if (result.isFromItem() || !isSaveModifiedItem) {
// save updated process
saveModifiedItem(result);
}
subMonitor.worked(1);
}
}
private static String getResultTaskInfor(UpdateResult result) {
if (result == null) {
return UpdatesConstants.EMPTY;
}
StringBuffer infor = new StringBuffer();
infor.append(result.getName());
infor.append(UpdatesConstants.LEFT_BRACKETS);
infor.append(result.getCategory());
infor.append(UpdatesConstants.SEGMENT);
infor.append(result.getJobInfor());
infor.append(UpdatesConstants.RIGHT_BRACKETS);
return infor.toString();
}
/*
* context
*/
@SuppressWarnings("unchecked")//$NON-NLS-1$
private static Command executeContextUpdates(UpdateResult result) {
if (result == null) {
return null;
}
Object object = result.getUpdateObject();
if (object instanceof Set) {
return new UpdateContextParameterCommand(result);
}
return null;
}
/*
* contextGroup
*/
@SuppressWarnings("unchecked")//$NON-NLS-1$
private static Command executeContextGroupUpdates(UpdateResult result) {
if (result == null) {
return null;
}
Object object = result.getUpdateObject();
if (object instanceof JobContext) {
return new UpdateContextParameterCommand(result);
}
return null;
}
/*
* joblet
*/
private static Command executeJobletNodesUpdates(UpdateResult result) {
if (result == null) {
return null;
}
Object parameter = result.getParameter();
if (parameter != null) {
return new UpdateJobletNodeCommand(result);
}
return null;
}
private static void upadateJobletReferenceInfor() {
List<IProcess2> openedProcessList = CorePlugin.getDefault().getDesignerCoreService()
.getOpenedProcess(RepositoryUpdateManager.getEditors());
for (IProcess2 proc : openedProcessList) {
proc.getUpdateManager().retrieveRefInformation();
}
}
/**
* DOC hyWang Comment method "checkandRefreshProcess".
*
* @param results
*/
private static void checkandRefreshProcess(final List<UpdateResult> results) {
for (UpdateResult tempResult : results) {
if (tempResult.getJob() instanceof IProcess2) {
IProcess2 process = (IProcess2) tempResult.getJob();
process.checkProcess();
}
}
}
}