// ============================================================================ // // Copyright (C) 2006-2016 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.dataprofiler.core.ui.utils; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature.Setting; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorReference; import org.eclipse.ui.IViewPart; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPartReference; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.WorkbenchException; import org.eclipse.ui.forms.widgets.ImageHyperlink; import org.talend.commons.exception.BusinessException; import org.talend.commons.exception.ExceptionHandler; import org.talend.core.model.metadata.builder.connection.MetadataTable; import org.talend.core.model.properties.ConnectionItem; import org.talend.core.model.properties.FolderItem; import org.talend.core.model.properties.FolderType; import org.talend.core.model.properties.Item; import org.talend.core.model.properties.Property; import org.talend.core.model.repository.ERepositoryObjectType; import org.talend.core.model.repository.Folder; import org.talend.core.model.repository.RepositoryViewObject; import org.talend.core.repository.constants.FileConstants; import org.talend.core.repository.model.FolderHelper; import org.talend.core.repository.model.ProxyRepositoryFactory; import org.talend.cwm.compare.exception.ReloadCompareException; import org.talend.cwm.compare.factory.ComparisonLevelFactory; import org.talend.cwm.compare.factory.comparisonlevel.FileMetadataTableComparisonLevel; import org.talend.cwm.dependencies.DependenciesHandler; import org.talend.cwm.management.i18n.Messages; import org.talend.dataprofiler.core.CorePlugin; import org.talend.dataprofiler.core.PluginConstant; import org.talend.dataprofiler.core.ui.action.actions.OpenItemEditorAction; import org.talend.dataprofiler.core.ui.editor.AbstractItemEditorInput; import org.talend.dataprofiler.core.ui.editor.analysis.AnalysisEditor; import org.talend.dataprofiler.core.ui.editor.analysis.AnalysisItemEditorInput; import org.talend.dataprofiler.core.ui.editor.analysis.MatchAnalysisEditor; import org.talend.dataprofiler.core.ui.editor.connection.ConnectionEditor; import org.talend.dataprofiler.core.ui.events.EventEnum; import org.talend.dataprofiler.core.ui.events.EventManager; import org.talend.dataprofiler.core.ui.views.DQRespositoryView; import org.talend.dataquality.analysis.Analysis; import org.talend.dataquality.analysis.AnalysisContext; import org.talend.dataquality.analysis.AnalysisType; import org.talend.dataquality.indicators.Indicator; import org.talend.dataquality.indicators.columnset.SimpleStatIndicator; import org.talend.dataquality.properties.TDQAnalysisItem; import org.talend.dq.helper.PropertyHelper; import org.talend.dq.helper.RepositoryNodeHelper; import org.talend.dq.helper.resourcehelper.AnaResourceFileHelper; import org.talend.dq.writer.EMFSharedResources; import org.talend.dq.writer.impl.ElementWriterFactory; import org.talend.repository.localprovider.model.LocalFolderHelper; import org.talend.repository.model.IRepositoryNode; import org.talend.repository.model.RepositoryNode; import org.talend.resource.EResourceConstant; import org.talend.resource.ResourceManager; import orgomg.cwm.foundation.softwaredeployment.DataProvider; import orgomg.cwm.objectmodel.core.Dependency; import orgomg.cwm.objectmodel.core.ModelElement; /** * DOC bZhou class global comment. Detailled comment */ public final class WorkbenchUtils { private static Logger log = Logger.getLogger(WorkbenchUtils.class); private static final int AUTO_CHANGE2DATA_PROFILER_TRUE = 1; private static final int AUTO_CHANGE2DATA_PROFILER_FALSE = 2; private static final boolean AUTO_CHANGE2DATA_PROFILER = true; private WorkbenchUtils() { } /** * DOC bZhou Comment method "changePerspective". * * @param perspectiveID */ public static void changePerspective(final String perspectiveID) { // TDQ-11403 make it is suspended until the runnable complete. Display.getCurrent().syncExec(new Runnable() { public void run() { IWorkbenchWindow activeWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); try { PlatformUI.getWorkbench().showPerspective(perspectiveID, activeWindow); } catch (WorkbenchException e) { log.error(e.getMessage(), e); } } }); } public static IFolder folder2IFolder(Folder folder) { IProject rootProject = ResourceManager.getRootProject(); return rootProject.getFolder(folder.getPath()); } public static IPath getPath(RepositoryViewObject viewObject) { return RepositoryNodeHelper.getPath(viewObject.getRepositoryNode()); } public static IFolder getFolder(RepositoryNode node) { // MOD qiongli 2011-1-18 if it is recyclebin,return the root folder IPath path = RepositoryNodeHelper.getPath(node); if (path.toString().equals(PluginConstant.EMPTY_STRING)) { return ResourceManager.getRootProject().getFolder(ResourceManager.getRootFolderLocation()); } return ResourceManager.getRootProject().getFolder(RepositoryNodeHelper.getPath(node)); } public static IFolder getFolder(RepositoryViewObject viewObject) { return getFolder((RepositoryNode) viewObject.getRepositoryNode()); } public static String getItemExtendtion(int classID) { String fileExtension = FileConstants.ITEM_EXTENSION; switch (classID) { case org.talend.dataquality.properties.PropertiesPackage.TDQ_ANALYSIS_ITEM: fileExtension = FileConstants.ANA_EXTENSION; break; case org.talend.dataquality.properties.PropertiesPackage.TDQ_REPORT_ITEM: fileExtension = FileConstants.REP_EXTENSION; break; case org.talend.dataquality.properties.PropertiesPackage.TDQ_INDICATOR_DEFINITION_ITEM: fileExtension = FileConstants.DEF_EXTENSION; break; case org.talend.dataquality.properties.PropertiesPackage.TDQ_PATTERN_ITEM: fileExtension = FileConstants.PAT_EXTENSION; break; case org.talend.dataquality.properties.PropertiesPackage.TDQ_BUSINESS_RULE_ITEM: fileExtension = FileConstants.RULE_EXTENSION; break; case org.talend.dataquality.properties.PropertiesPackage.TDQ_JRXML_ITEM: fileExtension = FileConstants.JRXML_EXTENSION; break; case org.talend.dataquality.properties.PropertiesPackage.TDQ_SOURCE_FILE_ITEM: fileExtension = FileConstants.SQL_EXTENSION; break; } return fileExtension; } public static IPath getFilePath(IRepositoryNode node) { Item item = node.getObject().getProperty().getItem(); IPath folderPath = RepositoryNodeHelper.getPath(node); String name = node.getObject() .getProperty() .getLabel() .concat("_") //$NON-NLS-1$ .concat(node.getObject().getProperty().getVersion()) .concat(".") //$NON-NLS-1$ .concat(WorkbenchUtils.getItemExtendtion(item != null ? item.eClass().getClassifierID() : node.getObject() .getProperty().getItem().eClass().getClassifierID())); IPath append = folderPath.append(new Path(name)); return append; } /** * * if it is TDQ_Data Profiling,TDQ_Libraries or metadata. * * @param folderItem * @return */ public static boolean isTDQOrMetadataRootFolder(FolderItem folderItem, org.talend.core.model.properties.Project newProject) { FolderHelper folderHelper = LocalFolderHelper.createInstance(newProject, ProxyRepositoryFactory.getInstance() .getRepositoryContext().getUser()); String path = folderHelper.getFullFolderPath(folderItem); if (path != null && (path.startsWith(RepositoryNodeHelper.PREFIX_TDQ) || path.startsWith(EResourceConstant.METADATA.getName()))) { return true; } return false; } /** * * Add qiongli: get the detail ERepositoryObjectType of folderItem. * * @param folderItem * @return */ public static ERepositoryObjectType getFolderContentType(FolderItem folderItem) { if (!folderItem.getType().equals(FolderType.SYSTEM_FOLDER_LITERAL)) { if (!(folderItem.getParent() instanceof FolderItem)) { return null; // appears only for a folder for expression builder ! } return getFolderContentType((FolderItem) folderItem.getParent()); } for (ERepositoryObjectType objectType : (ERepositoryObjectType[]) ERepositoryObjectType.values()) { String folderName; try { folderName = ERepositoryObjectType.getFolderName(objectType); } catch (Exception e) { // just catch exception to avoid the types who don't have folders continue; } if (folderName.contains("/")) { //$NON-NLS-1$ String[] folders = folderName.split("/"); //$NON-NLS-1$ FolderItem currentFolderItem = folderItem; boolean found = true; for (int i = folders.length - 1; i >= 0; i--) { if (!currentFolderItem.getProperty().getLabel().equals(folders[i])) { found = false; break; } if (i > 0) { if (!(currentFolderItem.getParent() instanceof FolderItem)) { found = false; break; } currentFolderItem = (FolderItem) currentFolderItem.getParent(); } } if (found) { return objectType; } } else { if (folderName.equals(folderItem.getProperty().getLabel())) { return objectType; } } } if (folderItem.getParent() instanceof FolderItem) { return getFolderContentType((FolderItem) folderItem.getParent()); } return null; } public static boolean isLinux() { return System.getProperty("os.name").toUpperCase().indexOf("LINUX") > -1; //$NON-NLS-1$ //$NON-NLS-2$ } public static boolean isWindows() { return System.getProperty("os.name").toUpperCase().indexOf("WIN") > -1; //$NON-NLS-1$ //$NON-NLS-2$ } public static boolean isWinXP() { return System.getProperty("os.name").toUpperCase().indexOf("WINDOWS XP") > -1; //$NON-NLS-1$ //$NON-NLS-2$ } public static boolean isWin7() { return System.getProperty("os.name").toUpperCase().indexOf("WINDOWS 7") > -1; //$NON-NLS-1$ //$NON-NLS-2$ } public static boolean isMac() { return System.getProperty("os.name").toUpperCase().indexOf("MAC") > -1; //$NON-NLS-1$ //$NON-NLS-2$ } /** * judgement one string equals another string dependency on the OS's case sensitive type. * * @param str1 * @param str2 * @return */ public static boolean equalsOS(String str1, String str2) { if (str1 == null || str2 == null) { return false; } else { if (isLinux() || isMac()) { return str1.equals(str2); } else if (isWindows()) { return str1.equalsIgnoreCase(str2); } else { // other os return str1.equals(str2); } } } /** * * Refresh the analysis and Connection which is openning */ @Deprecated public static void refreshCurrentAnalysisAndConnectionEditor() { List<IEditorReference> iEditorReference = getIEditorReference(AnalysisEditor.class.getName(), StringUtils.EMPTY); iEditorReference.addAll(getIEditorReference(ConnectionEditor.class.getName(), StringUtils.EMPTY)); iEditorReference.addAll(getIEditorReference(MatchAnalysisEditor.class.getName(), StringUtils.EMPTY)); closeAndOpenEditor(iEditorReference); } /** * close and open the editors same method {@link CorePlugin}.getDefault().itemIsOpening() MOD TDQ-8360 20140410 * yyin: will only operate the analysis who is related and has opened (by its observer --added when opening) * * @param iEditorReference */ private static void closeAndOpenEditor(List<IEditorReference> iEditorReference) { // Refresh current opened editors. IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); IWorkbenchPartReference activePartReference = activePage.getActivePartReference(); // MOD qiongli 2011-9-8 TDQ-3317.when focucs on DI perspective,don't refresh the open editors DQRespositoryView findView = (DQRespositoryView) activePage.findView(DQRespositoryView.ID); if (findView == null) { return; } if (iEditorReference.size() > 0) { try { for (IEditorReference editorRef : iEditorReference) { IEditorInput editorInput = editorRef.getEditorInput(); if (editorInput instanceof AbstractItemEditorInput) { AbstractItemEditorInput anaItemEditorInput = (AbstractItemEditorInput) editorInput; // close the editor activePage.closeEditor(editorRef.getEditor(false), false); // reopen the analysis new OpenItemEditorAction(new IRepositoryNode[] { anaItemEditorInput.getRepNode() }).run(); } } } catch (PartInitException e) { log.error(e); } } activePage.activate(activePartReference.getPart(false)); } /** * * Refresh the analysis which is openning * * @param String analysisName: can be StringUtils.EMPTY */ public static void refreshCurrentAnalysisEditor(String analysisName) { List<IEditorReference> iEditorReference = getIEditorReference(AnalysisEditor.class.getName(), analysisName); // update match analysis if any opened:TDQ-8267 added by yyin iEditorReference.addAll(getIEditorReference(MatchAnalysisEditor.class.getName(), analysisName)); closeAndOpenEditor(iEditorReference); } public static void nodifyDependedAnalysis(ConnectionItem connectionItem) { // Added TDQ-8360 20140410 yyin: notify each depended analysis EList<Dependency> clientDependencies = connectionItem.getConnection().getSupplierDependency(); for (Dependency dep : clientDependencies) { for (ModelElement mod : dep.getClient()) { if (!(mod instanceof Analysis)) { continue; } EventManager.getInstance().publish(mod, EventEnum.DQ_ANALYSIS_REFRESH_DATAPROVIDER_LIST, null); EventManager.getInstance().publish(mod, EventEnum.DQ_MATCH_ANALYSIS_REFRESH_DATAPROVIDER_LABEL, null); } } } /** * * Get Editors which is is same as editorID --used for the analysis editor only * * @param editorID * @param analysisName * @return */ private static List<IEditorReference> getIEditorReference(String editorID, String analysisName) { List<IEditorReference> returnCode = new ArrayList<IEditorReference>(); IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); IEditorReference[] editors = activePage.getEditorReferences(); if (editors != null) { for (IEditorReference editorRef : editors) { if (editorRef.getId().equals(editorID)) { IEditorInput editorInput; try { editorInput = editorRef.getEditorInput(); if (editorInput instanceof AbstractItemEditorInput) { AnalysisItemEditorInput anaItemEditorInput = (AnalysisItemEditorInput) editorInput; // if not pointed which analysis, add all opened ones. if (StringUtils.isEmpty(analysisName) || StringUtils.equals(analysisName, anaItemEditorInput.getModel().getName())) { returnCode.add(editorRef); } } } catch (PartInitException e) { log.error(e, e); } } } } return returnCode; } public static void refreshAnalysesNode() { IRepositoryNode analysesNode = RepositoryNodeHelper.getDataProfilingFolderNode(EResourceConstant.ANALYSIS); if (analysesNode != null) { CorePlugin.getDefault().refreshDQView(analysesNode); } } public static void refreshMetadataNode() { // database connection node IRepositoryNode dbNode = RepositoryNodeHelper.getMetadataFolderNode(EResourceConstant.DB_CONNECTIONS); if (dbNode != null) { CorePlugin.getDefault().refreshDQView(dbNode); } // delimited file connection node IRepositoryNode dfNode = RepositoryNodeHelper.getMetadataFolderNode(EResourceConstant.FILEDELIMITED); if (dfNode != null) { CorePlugin.getDefault().refreshDQView(dfNode); } // hadoop cluster connection node IRepositoryNode hcNode = RepositoryNodeHelper.getMetadataFolderNode(EResourceConstant.HADOOP_CLUSTER); if (dfNode != null) { CorePlugin.getDefault().refreshDQView(hcNode); } } /** * * DOC qiongli TDQ-3317:move this method from ReloadDatabaseAction. to this class . * * @param oldDataProvider * @throws PartInitException */ public static void impactExistingAnalyses(DataProvider oldDataProvider) throws PartInitException { EList<Dependency> clientDependencies = oldDataProvider.getSupplierDependency(); List<Analysis> unsynedAnalyses = new ArrayList<Analysis>(); for (Dependency dep : clientDependencies) { for (ModelElement mod : dep.getClient()) { // MOD mzhao 2009-08-24 The dependencies include "Property" and "Analysis" if (!(mod instanceof Analysis)) { continue; } Analysis ana = (Analysis) mod; unsynedAnalyses.add(ana); } for (Analysis analysis : unsynedAnalyses) { // Reload. IFile file = getTempAnalysisFile(analysis); Analysis tempAnalysis = (Analysis) AnaResourceFileHelper.getInstance().getModelElement(file); // MOD qiongli 2010-8-17,bug 14977 if (tempAnalysis != null) { Resource eResource = tempAnalysis.eResource(); Map<EObject, Collection<Setting>> referenceMaps = EcoreUtil.UnresolvedProxyCrossReferencer.find(eResource); Iterator<EObject> it = referenceMaps.keySet().iterator(); ModelElement eobj = null; boolean isModified = false; while (it.hasNext()) { eobj = (ModelElement) it.next(); Collection<Setting> settings = referenceMaps.get(eobj); for (Setting setting : settings) { if (setting.getEObject() instanceof AnalysisContext) { tempAnalysis.getContext().getAnalysedElements().remove(eobj); isModified = true; } else if (setting.getEObject() instanceof Indicator) { // when remove a column from the column set analysis, it should only remove this column // from the simple stat indicator, but not remove the simple stat indicator, which is // the only indicator in the column set analysis. (Added TDQ-8842 20140512 yyin) if (AnalysisType.COLUMN_SET.equals(tempAnalysis.getParameters().getAnalysisType())) { ((SimpleStatIndicator) setting.getEObject()).getAnalyzedColumns().remove(eobj);// ~ } else { tempAnalysis.getResults().getIndicators().remove(setting.getEObject()); } isModified = true; } } } if (isModified) { saveTempAnalysis(file, tempAnalysis); } // Should reopen this analyis's editor if it is opened now. what ever it is modified or not. EventManager.getInstance().publish(tempAnalysis.getName(), EventEnum.DQ_ANALYSIS_REOPEN_EDITOR, null); } } } } private static void saveTempAnalysis(IFile file, Analysis tempAnalysis) { Property tempAnaProperty = PropertyHelper.getProperty(file); // only when all elements of the data provider are removed from the analysis, the dependency between // them should be removed too. If only parts of them removed, the dependendy should not be removed. // TDQ-8267, since the dependency is removed, the connection in the analysis context should also be // removed if (tempAnaProperty == null) { log.error(Messages.getString("WorkbenchUtils.fialToSaveImapctAnalysis", tempAnalysis.getName())); //$NON-NLS-1$ return; } if (tempAnalysis.getContext().getAnalysedElements().isEmpty()) { DependenciesHandler.getInstance().removeConnDependencyAndSave((TDQAnalysisItem) tempAnaProperty.getItem()); } else { ElementWriterFactory.getInstance().createAnalysisWrite().save(tempAnaProperty.getItem(), false); } } /** * DOC yyin Comment method "getTempAnalysis". * * @param analysis * @return */ private static IFile getTempAnalysisFile(Analysis analysis) { Resource eResource = analysis.eResource(); if (eResource == null) { return null; } EMFSharedResources.getInstance().unloadResource(eResource.getURI().toString()); IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); // MOD by zshen for bug 12316 to avoid null argument. Path path = new Path(analysis.getFileName() == null ? eResource.getURI().toPlatformString(false) : analysis.getFileName()); return root.getFile(path); } /** * Reload the metadata table of the current file connection, when the file connection changed schema: if the * analysis 's analyzed columns are in the changed schema: compare the columns, remain the columns with same name, * remove the columns not in new schema, and add the new columns in new schema. TDQ-8360 20140324 yyin * * @param MetadataTable with new schema */ public static void reloadMetadataOfDelimitedFile(MetadataTable metadataTable) throws BusinessException { FileMetadataTableComparisonLevel creatComparisonLevel = (FileMetadataTableComparisonLevel) ComparisonLevelFactory .creatComparisonLevel(metadataTable); try { creatComparisonLevel.reloadCurrentLevelElement(); } catch (ReloadCompareException e) { log.error(e, e); throw new BusinessException(Messages.getString("WorkbenchUtils.failToReloadMetadataOfDelimitedFile"), e); } } /** * Get viewPart with special partId. If the active page doesn't exsit, the method will return null; Else, it will * get the viewPart and focus it. if the viewPart closed, it will be opened. * * @param viewId the identifier of viewPart * @return */ public static IViewPart getAndOpenView(String viewId) { return getView(viewId, true); } /** * Get viewPart with special partId. If the active page doesn't exsit, the method will return null; Else, it will * get the viewPart and focus it. if the viewPart closed, it will return null too. * * @param viewId the identifier of viewPart * @param openIfClose decide whether we will open the view when it is closing * @return */ public static IViewPart getView(String viewId, boolean openIfClose) { return getView(viewId, openIfClose, true); } /** * Get viewPart with special partId. If the active page doesn't exsit, the method will return null; Else, it will * get the viewPart and focus it or not. if the viewPart closed, it will return null too. * * @param viewId the identifier of viewPart * @param openIfClose decide whether we will open the view when it is closing * @param bringToTop decide whether we will bring the part To Top * @return */ public static IViewPart getView(String viewId, boolean openIfClose, boolean bringToTop) { IWorkbenchWindow activeWorkbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (activeWorkbenchWindow == null) { return null; } IWorkbenchPage page = activeWorkbenchWindow.getActivePage(); if (page == null) { return null; } IViewPart part = page.findView(viewId); if (part == null) { try { if (openIfClose) { part = page.showView(viewId); } } catch (Exception e) { ExceptionHandler.process(e, Level.ERROR); } } else { if (bringToTop) { page.bringToTop(part); } } return part; } /** * use this method to set ImageHyperlink's image insteadof using ImageHyperlink.setImage() to avoid new Image() * NOTE: this method only can be used when the ImageHyperlink is alway enable. * * @param imageHyperlink * @param image */ public static void setHyperlinkImage(ImageHyperlink imageHyperlink, Image image) { imageHyperlink.setActiveImage(image); imageHyperlink.setBackgroundImage(image); } }