// ============================================================================ // // 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.projectsetting; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.gef.commands.Command; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.ITreeViewerListener; import org.eclipse.jface.viewers.TreeExpansionEvent; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.ui.IEditorReference; import org.eclipse.ui.IViewSite; import org.eclipse.ui.PlatformUI; import org.talend.commons.exception.PersistenceException; import org.talend.commons.ui.runtime.exception.ExceptionHandler; import org.talend.commons.ui.runtime.image.ECoreImage; import org.talend.commons.ui.runtime.image.ImageProvider; import org.talend.core.model.context.ContextUtils; import org.talend.core.model.metadata.builder.connection.Connection; import org.talend.core.model.process.EParameterFieldType; import org.talend.core.model.process.Element; import org.talend.core.model.process.IElementParameter; import org.talend.core.model.process.IProcess; import org.talend.core.model.process.IProcess2; import org.talend.core.model.properties.ConnectionItem; import org.talend.core.model.properties.ProcessItem; import org.talend.core.model.properties.Property; import org.talend.core.model.repository.ERepositoryObjectType; import org.talend.core.model.repository.RepositoryManager; import org.talend.core.repository.model.ProxyRepositoryFactory; import org.talend.designer.core.i18n.Messages; import org.talend.designer.core.model.components.EParameterName; import org.talend.designer.core.model.components.EmfComponent; import org.talend.designer.core.model.process.jobsettings.JobSettingsConstants; import org.talend.designer.core.model.utils.emf.talendfile.ParametersType; import org.talend.designer.core.ui.editor.cmd.ChangeValuesFromRepository; import org.talend.designer.core.ui.editor.cmd.LoadProjectSettingsCommand; import org.talend.designer.core.ui.editor.process.Process; import org.talend.designer.core.ui.editor.update.UpdateManagerUtils; import org.talend.designer.core.ui.views.properties.WidgetFactory; import org.talend.designer.core.utils.DetectContextVarsUtils; import org.talend.repository.ProjectManager; import org.talend.repository.UpdateRepositoryUtils; import org.talend.repository.model.IProxyRepositoryFactory; import org.talend.repository.model.IRepositoryNode; import org.talend.repository.model.IRepositoryNode.ENodeType; import org.talend.repository.model.ProjectRepositoryNode; import org.talend.repository.model.RepositoryNode; import org.talend.repository.preference.ProjectSettingPage; import org.talend.repository.ui.views.IRepositoryView; import org.talend.repository.ui.views.RepositoryLabelProvider; import org.talend.repository.ui.wizards.metadata.ShowAddedContextdialog; import org.talend.repository.viewer.ui.provider.RepositoryContentProvider; import org.talend.repository.viewer.ui.provider.RepositoryNameSorter; import org.talend.repository.viewer.ui.viewer.CheckboxRepositoryTreeViewer; /** * DOC achen class global comment. Detailled comment */ public class StatLogsAndImplicitcontextTreeViewPage extends ProjectSettingPage { private IRepositoryView repositoryView; private final IProxyRepositoryFactory factory = ProxyRepositoryFactory.getInstance(); final List<IProcess2> opendProcess = UpdateManagerUtils.getOpenedProcess(); // implicit context tree private CheckboxRepositoryTreeViewer viewer; private AllJobContentProvider contentProvider; private List<RepositoryNode> checkedObjects = new ArrayList<RepositoryNode>(); private List<RepositoryNode> addedObjects = new ArrayList<RepositoryNode>(); private List<RepositoryNode> removedObjects = new ArrayList<RepositoryNode>(); // stats and log tree private CheckboxRepositoryTreeViewer statViewer; private AllJobContentProvider statContentProvider; private List<RepositoryNode> statCheckedObjects = new ArrayList<RepositoryNode>(); private List<RepositoryNode> statAddedObjects = new ArrayList<RepositoryNode>(); private List<RepositoryNode> statRemovedObjects = new ArrayList<RepositoryNode>(); private WidgetFactory widgetFactory = new WidgetFactory(); private boolean statsLogAddContextModel = false; private boolean implicitAddContextModel = false; private boolean addContext = false; private IEditorReference[] editors = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() .getEditorReferences(); // private IDesignerCoreService coreService = CorePlugin.getDefault().getDesignerCoreService(); /* * (non-Javadoc) * * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite) */ @Override protected Control createContents(Composite parent) { Composite composite = widgetFactory.createComposite(parent, SWT.NONE); // composite.setLayout(new FillLayout()); GridLayout layout = new GridLayout(); layout.marginLeft = 5; layout.marginRight = 5; layout.numColumns = 2; layout.makeColumnsEqualWidth = true; composite.setLayout(layout); repositoryView = RepositoryManager.getRepositoryView(); createImplicitcontextTree(composite); createStatTree(composite); IProxyRepositoryFactory facto = ProxyRepositoryFactory.getInstance(); if (facto.isUserReadOnlyOnCurrentProject()) { composite.setEnabled(false); } return composite; } @Override public void dispose() { if (widgetFactory != null) { widgetFactory.dispose(); } super.dispose(); } private void createImplicitcontextTree(Composite composite) { Group g = widgetFactory.createGroup(composite, Messages.getString("ExtraComposite.ImplicitContextSettings")); //$NON-NLS-1$ GridData gd = new GridData(GridData.FILL_BOTH); g.setLayoutData(gd); g.setLayout(new FillLayout()); viewer = new CheckboxRepositoryTreeViewer(g, SWT.MULTI | SWT.V_SCROLL); contentProvider = new AllJobContentProvider(repositoryView); viewer.setContentProvider(contentProvider); viewer.setLabelProvider(new RepositoryLabelProvider(repositoryView)); viewer.setSorter(new RepositoryNameSorter()); IViewSite viewSite = repositoryView.getViewSite(); viewer.setInput(viewSite); // This only tree listener aim is to change open/close icons on folders : viewer.addTreeListener(new ITreeViewerListener() { @Override public void treeCollapsed(TreeExpansionEvent event) { RepositoryNode node = (RepositoryNode) event.getElement(); if (node.getType().equals(ENodeType.SIMPLE_FOLDER)) { TreeItem item = getObject(viewer.getTree(), event.getElement()); if (item != null) { item.setImage(ImageProvider.getImage(ECoreImage.FOLDER_CLOSE_ICON)); } } } @Override public void treeExpanded(TreeExpansionEvent event) { RepositoryNode node = (RepositoryNode) event.getElement(); if (node.getType().equals(ENodeType.SIMPLE_FOLDER)) { TreeItem item = getObject(viewer.getTree(), event.getElement()); if (item != null) { item.setImage(ImageProvider.getImage(ECoreImage.FOLDER_OPEN_ICON)); } } } }); viewer.addCheckStateListener(new ICheckStateListener() { @Override public void checkStateChanged(CheckStateChangedEvent event) { RepositoryNode node = (RepositoryNode) event.getElement(); List<RepositoryNode> objects = new ArrayList<RepositoryNode>(); processItems(objects, node); if (event.getChecked()) { addedObjects.addAll(objects); removedObjects.removeAll(objects); checkedObjects.addAll(addedObjects); } else { addedObjects.removeAll(objects); removedObjects.addAll(objects); checkedObjects.removeAll(objects); } // set checked viewer.setCheckedElements(checkedObjects.toArray()); // viewer.refresh(); } }); RepositoryNode[] nodes = contentProvider.getContents(); List<RepositoryNode> objects = new ArrayList<RepositoryNode>(); if (nodes != null) { for (RepositoryNode n : nodes) { processItems(objects, n); for (RepositoryNode node : objects) { if (isUseProjectSetting(node)) { if (!checkedObjects.contains(node)) { checkedObjects.add(node); } } } } } viewer.setCheckedElements(checkedObjects.toArray()); if (nodes != null) { viewer.setExpandedElements(nodes); } } private void createStatTree(Composite composite) { Group g = widgetFactory.createGroup(composite, Messages.getString("StatsAndLogsComposite.StatsLogsSettings")); //$NON-NLS-1$ GridData gd = new GridData(GridData.FILL_BOTH); g.setLayoutData(gd); g.setLayout(new FillLayout()); statViewer = new CheckboxRepositoryTreeViewer(g, SWT.MULTI | SWT.V_SCROLL); statContentProvider = new AllJobContentProvider(repositoryView); statViewer.setContentProvider(statContentProvider); statViewer.setLabelProvider(new RepositoryLabelProvider(repositoryView)); statViewer.setSorter(new RepositoryNameSorter()); IViewSite viewSite = repositoryView.getViewSite(); statViewer.setInput(viewSite); // This only tree listener aim is to change open/close icons on folders : statViewer.addTreeListener(new ITreeViewerListener() { @Override public void treeCollapsed(TreeExpansionEvent event) { RepositoryNode node = (RepositoryNode) event.getElement(); if (node.getType().equals(ENodeType.SIMPLE_FOLDER)) { TreeItem item = getObject(statViewer.getTree(), event.getElement()); if (item != null) { item.setImage(ImageProvider.getImage(ECoreImage.FOLDER_CLOSE_ICON)); } } } @Override public void treeExpanded(TreeExpansionEvent event) { RepositoryNode node = (RepositoryNode) event.getElement(); if (node.getType().equals(ENodeType.SIMPLE_FOLDER)) { TreeItem item = getObject(statViewer.getTree(), event.getElement()); if (item != null) { item.setImage(ImageProvider.getImage(ECoreImage.FOLDER_OPEN_ICON)); } } } }); statViewer.addCheckStateListener(new ICheckStateListener() { @Override public void checkStateChanged(CheckStateChangedEvent event) { RepositoryNode node = (RepositoryNode) event.getElement(); List<RepositoryNode> objects = new ArrayList<RepositoryNode>(); processItems(objects, node); if (event.getChecked()) { statAddedObjects.addAll(objects); statRemovedObjects.removeAll(objects); statCheckedObjects.addAll(objects); } else { statAddedObjects.removeAll(objects); statRemovedObjects.addAll(objects); statCheckedObjects.removeAll(objects); } // set checked statViewer.setCheckedElements(statCheckedObjects.toArray()); // viewer.refresh(); } }); RepositoryNode[] nodes = statContentProvider.getContents(); List<RepositoryNode> objects = new ArrayList<RepositoryNode>(); if (nodes != null) { for (RepositoryNode n : nodes) { processItems(objects, n); for (RepositoryNode node : objects) { if (isStatUseProjectSetting(node)) { if (!statCheckedObjects.contains(node)) { statCheckedObjects.add(node); } } } } } statViewer.setCheckedElements(statCheckedObjects.toArray()); if (nodes != null) { statViewer.setExpandedElements(nodes); } } private boolean isUseProjectSetting(RepositoryNode node) { Property property = node.getObject().getProperty(); ProcessItem pItem = (ProcessItem) property.getItem(); ParametersType pType = pItem.getProcess().getParameters(); String implictB = ElementParameter2ParameterType.getParameterValue(pType, EParameterName.IMPLICITCONTEXT_USE_PROJECT_SETTINGS.getName()); if (implictB != null && "true".equals(implictB)) { //$NON-NLS-1$ return true; } else { return false; } } private boolean isStatUseProjectSetting(RepositoryNode node) { Property property = node.getObject().getProperty(); ProcessItem pItem = (ProcessItem) property.getItem(); ParametersType pType = pItem.getProcess().getParameters(); String statB = ElementParameter2ParameterType.getParameterValue(pType, EParameterName.STATANDLOG_USE_PROJECT_SETTINGS.getName()); if (statB != null && "true".equals(statB)) { //$NON-NLS-1$ return true; } else { return false; } } private boolean isOpenProcess(RepositoryNode node) { Property property = node.getObject().getProperty(); if (property.getItem() instanceof ProcessItem) { for (IProcess process : opendProcess) { if (process.getId().equals(property.getId()) && process.getName().equals(property.getLabel()) && process.getVersion().equals(property.getVersion())) { return true; } } } return false; } private void processItems(List<RepositoryNode> objects, RepositoryNode node) { if (node == null) { return; } if (node.getType() == ENodeType.REPOSITORY_ELEMENT) { if (node.getObject() != null) { objects.add(node); } } else { for (IRepositoryNode child : node.getChildren()) { processItems(objects, (RepositoryNode) child); } } } private TreeItem getObject(Tree tree, Object objectToFind) { for (TreeItem item : tree.getItems()) { TreeItem toReturn = getObject(item, objectToFind); if (toReturn != null) { return toReturn; } } return null; } private TreeItem getObject(TreeItem parent, Object objectToFind) { for (TreeItem currentChild : parent.getItems()) { if (objectToFind.equals(currentChild.getData())) { return currentChild; } TreeItem toReturn = getObject(currentChild, objectToFind); if (toReturn != null) { return toReturn; } } return null; } class AllJobContentProvider extends RepositoryContentProvider { public AllJobContentProvider(IRepositoryView v) { super(v); } @Override public Object[] getElements(Object parent) { IRepositoryView view = getView(); if (view == null || parent.equals(view.getViewSite())) { return getContents(); } return getChildren(parent); } RepositoryNode[] getContents() { ProjectRepositoryNode root = getRoot(); if (root != null) { RepositoryNode rootRepositoryNode = root.getRootRepositoryNode(ERepositoryObjectType.PROCESS); if (rootRepositoryNode != null) { return new RepositoryNode[] { rootRepositoryNode }; } } return null; } } /* * (non-Javadoc) * * @see org.eclipse.jface.preference.PreferencePage#performApply() */ @Override protected void performApply() { save(); super.performApply(); } /* * (non-Javadoc) * * @see org.eclipse.jface.preference.PreferencePage#performOk() */ @Override public boolean performOk() { save(); return super.performOk(); } private void saveProcess(RepositoryNode node, String paramName, Boolean isUseProjectSettings, boolean addContextModel, Map<String, Set<String>> contextVars, IProgressMonitor monitor) { Property property = node.getObject().getProperty(); ProcessItem pItem = (ProcessItem) property.getItem(); ParametersType pType = pItem.getProcess().getParameters(); if (isOpenProcess(node)) { Process process = getProcess(opendProcess, node); LoadProjectSettingsCommand command = new LoadProjectSettingsCommand(process, paramName, isUseProjectSettings); exeCommand(process, command); Element elem = null; String propertyName = ""; String propertyTypeName = ""; if (EParameterName.IMPLICITCONTEXT_USE_PROJECT_SETTINGS.getName().equals(paramName)) { elem = (Element) pro.getInitialContextLoad(); propertyName = JobSettingsConstants.getExtraParameterName(EParameterName.PROPERTY_TYPE.getName()) + ':' + EParameterName.REPOSITORY_PROPERTY_TYPE.getName(); propertyTypeName = JobSettingsConstants.getExtraParameterName(EParameterName.PROPERTY_TYPE.getName()) + ':' + EParameterName.PROPERTY_TYPE.getName(); } else if (EParameterName.STATANDLOG_USE_PROJECT_SETTINGS.getName().equals(paramName)) { elem = (Element) pro.getStatsAndLog(); propertyName = EParameterName.PROPERTY_TYPE.getName() + ':' + EParameterName.REPOSITORY_PROPERTY_TYPE.getName(); propertyTypeName = EParameterName.PROPERTY_TYPE.getName() + ':' + EParameterName.PROPERTY_TYPE.getName(); } IElementParameter ptParam = elem.getElementParameterFromField(EParameterFieldType.PROPERTY_TYPE); if (ptParam != null) { IElementParameter propertyElem = ptParam.getChildParameters().get(EParameterName.PROPERTY_TYPE.getName()); Object proValue = propertyElem.getValue(); if (proValue instanceof String && ((String) proValue).equalsIgnoreCase(EmfComponent.REPOSITORY)) { IElementParameter repositoryElem = ptParam.getChildParameters().get( EParameterName.REPOSITORY_PROPERTY_TYPE.getName()); String value = (String) repositoryElem.getValue(); ConnectionItem connectionItem = UpdateRepositoryUtils.getConnectionItemByItemId(value); if (connectionItem != null) { Connection connection = connectionItem.getConnection(); ChangeValuesFromRepository cmd = new ChangeValuesFromRepository(process, connection, addContextModel ? propertyName : propertyTypeName, value); cmd.ignoreContextMode(true); exeCommand(process, cmd); } } } monitor.worked(100); } else { ElementParameter2ParameterType.setParameterValue(pType, paramName, isUseProjectSettings); if (isUseProjectSettings) { if (EParameterName.IMPLICITCONTEXT_USE_PROJECT_SETTINGS.getName().equals(paramName)) { ProjectSettingManager.reloadImplicitValuesFromProjectSettings(pType, ProjectManager.getInstance() .getCurrentProject()); } else if (EParameterName.STATANDLOG_USE_PROJECT_SETTINGS.getName().equals(paramName)) { ProjectSettingManager.reloadStatsAndLogFromProjectSettings(pType, ProjectManager.getInstance() .getCurrentProject()); } } if (addContextModel && contextVars != null && !contextVars.isEmpty() && ContextUtils.getAllContextItem() != null) { ContextUtils.addInContextModelForProcessItem(pItem, contextVars, ContextUtils.getAllContextItem()); } try { factory.save(pItem); monitor.worked(100); } catch (PersistenceException e) { ExceptionHandler.process(e); } } } private void saveChangedNode(String paramName, boolean addContextModel, Map<String, Set<String>> contextVars, IProgressMonitor monitor) { List<RepositoryNode> checked = new ArrayList<RepositoryNode>(); List<RepositoryNode> unChecked = new ArrayList<RepositoryNode>(); if (EParameterName.IMPLICITCONTEXT_USE_PROJECT_SETTINGS.getName().equals(paramName)) { checked = addedObjects; unChecked = removedObjects; } else if (EParameterName.STATANDLOG_USE_PROJECT_SETTINGS.getName().equals(paramName)) { checked = statAddedObjects; unChecked = statRemovedObjects; } for (RepositoryNode node : checked) { saveProcess(node, paramName, Boolean.TRUE, addContextModel, contextVars, monitor); } for (RepositoryNode node : unChecked) { saveProcess(node, paramName, Boolean.FALSE, addContextModel, contextVars, monitor); } } private void save() { if (viewer == null) { return; } final IRunnableWithProgress runnable = new IRunnableWithProgress() { @Override public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { monitor.beginTask( Messages.getString("StatLogsAndImplicitcontextTreeViewPage.SaveProjectSettings"), (addedObjects.size() + statAddedObjects.size()) * 100); //$NON-NLS-1$ addContext = false; statsLogAddContextModel = false; implicitAddContextModel = false; Map<String, Set<String>> implicitContextVars = null; Map<String, Set<String>> statsLogContextVars = null; // if add some object to use project setting ,check context model if (!addedObjects.isEmpty()) { if (pro != null) { Element implicitContextLoad = (Element) pro.getInitialContextLoad(); implicitContextVars = DetectContextVarsUtils.detectByPropertyType(implicitContextLoad, true); } } if (!statAddedObjects.isEmpty()) { if (pro != null) { Element statsAndLog = (Element) pro.getStatsAndLog(); statsLogContextVars = DetectContextVarsUtils.detectByPropertyType(statsAndLog, true); } } // if statslog and implicit use the same connection only show add context dialog one time if (implicitContextVars != null && statsLogContextVars != null && !implicitContextVars.isEmpty() && !statsLogContextVars.isEmpty() && implicitContextVars.keySet().toArray()[0].equals(statsLogContextVars.keySet().toArray()[0])) { showAddContextDialog(implicitContextVars); if (addContext) { statsLogAddContextModel = true; implicitAddContextModel = true; } } else { if (implicitContextVars != null && !implicitContextVars.isEmpty()) { showAddContextDialog(implicitContextVars); if (addContext) { implicitAddContextModel = true; } } if (statsLogContextVars != null && !statsLogContextVars.isEmpty()) { showAddContextDialog(statsLogContextVars); if (addContext) { statsLogAddContextModel = true; } } } saveChangedNode(EParameterName.IMPLICITCONTEXT_USE_PROJECT_SETTINGS.getName(), implicitAddContextModel, implicitContextVars, monitor); saveChangedNode(EParameterName.STATANDLOG_USE_PROJECT_SETTINGS.getName(), statsLogAddContextModel, statsLogContextVars, monitor); monitor.done(); } }; final ProgressMonitorDialog dialog = new ProgressMonitorDialog(null); try { dialog.run(true, true, runnable); } catch (InvocationTargetException e) { ExceptionHandler.process(e); } catch (InterruptedException e) { ExceptionHandler.process(e); } } private void showAddContextDialog(Map<String, Set<String>> vars) { final Map<String, Set<String>> contextVars = vars; Display disp = Display.getCurrent(); if (disp == null) { disp = Display.getDefault(); } if (disp != null) { disp.syncExec(new Runnable() { @Override public void run() { ShowAddedContextdialog showDialog = new ShowAddedContextdialog(contextVars, true); if (showDialog.open() == Window.OK) { addContext = true; } } }); } } private org.talend.designer.core.ui.editor.process.Process getProcess(List<IProcess2> list, RepositoryNode p) { for (int i = 0; i < list.size(); i++) { if (list.get(i).getId().equals(p.getId())) { return (org.talend.designer.core.ui.editor.process.Process) list.get(i); } } return null; } private void exeCommand(final Process process, final Command cmd) { Display display = Display.getCurrent(); if (display == null) { display = Display.getDefault(); } if (display != null) { display.asyncExec(new Runnable() { @Override public void run() { process.getCommandStack().execute(cmd); } }); } else { cmd.execute(); } } /* * (non-Javadoc) * * @see org.talend.repository.preference.ProjectSettingPage#refresh() */ @Override public void refresh() { // TODO Auto-generated method stub } }