/* * � Copyright IBM Corp. 2015, 2016 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package com.ibm.xsp.extlib.designer.bluemix.util; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.URL; import java.util.Properties; import lotus.domino.Database; import lotus.domino.Document; import lotus.domino.DocumentCollection; import lotus.domino.NotesException; import org.cloudfoundry.client.lib.CloudFoundryException; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.preference.PreferenceDialog; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorReference; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.browser.IWebBrowser; import org.eclipse.ui.browser.IWorkbenchBrowserSupport; import org.eclipse.ui.dialogs.PreferencesUtil; import com.ibm.commons.iloader.node.validators.UrlValidator; import com.ibm.commons.iloader.node.validators.support.Messages; import com.ibm.commons.util.StringUtil; import com.ibm.designer.domino.ide.resources.DominoResourcesPlugin; import com.ibm.designer.domino.ide.resources.NsfException; import com.ibm.designer.domino.ide.resources.metamodel.IMetaModelConstants; import com.ibm.designer.domino.ide.resources.project.DominoDesignerProject; import com.ibm.designer.domino.ide.resources.project.IDominoDesignerProject; import com.ibm.designer.domino.napi.NotesAPIException; import com.ibm.designer.domino.napi.NotesSession; import com.ibm.designer.prj.resources.commons.IDesignElement; import com.ibm.xsp.extlib.designer.bluemix.BluemixLogger; import com.ibm.xsp.extlib.designer.bluemix.manifest.editor.ManifestMetaModel.BluemixManifestEditorInput; import com.ibm.xsp.extlib.designer.bluemix.manifest.editor.ManifestMultiPageEditor; import com.ibm.xsp.extlib.designer.bluemix.preference.PreferencePage; import static com.ibm.xsp.extlib.designer.bluemix.preference.PreferenceKeys.*; /** * @author Gary Marjoram * */ public class BluemixUtil { // Get the root cause of a throwable public static Throwable getRootCause(Throwable throwable) { if ((throwable.getCause() != null) && (throwable.getCause() != throwable)) return getRootCause(throwable.getCause()); return throwable; } // Get some text from a throwable for display public static String getErrorText(Throwable t) { String msg = null; Throwable root = getRootCause(t); if (root instanceof CloudFoundryException) { msg = ((CloudFoundryException)root).getDescription(); } else if (root instanceof NotesException) { msg = ((NotesException)root).text; } if (StringUtil.isEmpty(msg)) { msg = root.getMessage(); } if (StringUtil.isEmpty(msg)) { msg = root.toString(); } return msg; } // Is the Bluemix Server configured ? public static boolean isServerConfigured() { // Check for Blanks if(StringUtil.isEmpty(PreferencePage.getSecurePreference(KEY_BLUEMIX_SERVER_USERNAME, ""))) { return false; } if(StringUtil.isEmpty(PreferencePage.getSecurePreference(KEY_BLUEMIX_SERVER_URL, ""))) { return false; } if(StringUtil.isEmpty(PreferencePage.getSecurePreference(KEY_BLUEMIX_SERVER_PASSWORD, ""))) { return false; } // Validate the URL UrlValidator urlValidator = new UrlValidator(true); if (!urlValidator.isValid(PreferencePage.getSecurePreference(KEY_BLUEMIX_SERVER_URL, ""), new Messages())) { return false; } return true; } // Prompt the user to open the Server preferences public static void displayConfigureServerDialog() { String msg = BluemixUtil.productizeString("The %BM_PRODUCT% Server connection is not configured correctly. Open the %BM_PRODUCT% preferences?"); // $NLX-BluemixUtil.TheIBMBluemixServerconnectionisnotco-1$ if(MessageDialog.openQuestion(null, "Server Configuration", msg)) { // $NLX-BluemixUtil.ServerConfiguration-1$ PreferenceDialog dialog = PreferencesUtil.createPreferenceDialogOn(null, PreferencePage.BLUEMIX_PREF_PAGE, null, null); dialog.open(); } } // Given the full path of a database return the NSF file name public static String getNsfName(String dbName) { if (dbName.contains(File.separator)) { int idx = dbName.lastIndexOf(File.separator); return dbName.substring(idx+1); } return(dbName); } // Open a URL in the default browser public static void openUrlInDefaultBrowser(URL url) { IWorkbenchBrowserSupport support = PlatformUI.getWorkbench().getBrowserSupport(); try { IWebBrowser browser = support.getExternalBrowser(); browser.openURL(url); } catch (PartInitException e) { if(BluemixLogger.BLUEMIX_LOGGER.isErrorEnabled()){ BluemixLogger.BLUEMIX_LOGGER.errorp(BluemixUtil.class, "openUrlInDefaultBrowser", e, "Failed to initialize browser part"); // $NON-NLS-1$ $NLE-BluemixUtil.Failedtoinitializebrowserpart-2$ } } catch (Exception e) { if(BluemixLogger.BLUEMIX_LOGGER.isErrorEnabled()){ BluemixLogger.BLUEMIX_LOGGER.errorp(BluemixUtil.class, "openUrlInDefaultBrowser", e, "Failed to launch browser"); // $NON-NLS-1$ $NLE-BluemixUtil.Failedtolaunchbrowser-2$ } } } // Given a project return the manifest editor if open public static ManifestMultiPageEditor getManifestEditor(IDominoDesignerProject project) { for (IEditorReference ref : PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getEditorReferences()) { try { if (ref.getEditorInput() instanceof BluemixManifestEditorInput) { if (((BluemixManifestEditorInput)ref.getEditorInput()).getDesignerProject() == project) { return (ManifestMultiPageEditor) ref.getEditor(false); } } } catch (PartInitException e) { if (BluemixLogger.BLUEMIX_LOGGER.isErrorEnabled()) { BluemixLogger.BLUEMIX_LOGGER.errorp(BluemixUtil.class, "getManifestEditor", e, "Failed to get manifest editor"); // $NON-NLS-1$ $NLE-BluemixUtil.Failedtogetmanifesteditor-2$ } } } return null; } // Get the Notes data directory public static String getNotesDataDir() throws Throwable { final String[] result = new String[1]; Display.getDefault().syncExec(new Runnable(){ public void run() { NotesSession session = null; try { session = new NotesSession(); result[0] = session.getDataDirectory(); } finally { if(session != null){ try { session.recycle(); } catch (NotesAPIException e) { if (BluemixLogger.BLUEMIX_LOGGER.isErrorEnabled()) { BluemixLogger.BLUEMIX_LOGGER.errorp(BluemixUtil.class, "getNotesDataDir", e, "Failed to recycle session"); // $NON-NLS-1$ $NLE-BluemixUtil.Failedtorecyclesession-2$ } } } } } }); return result[0]; } // Given a source and dest copies a file public static void copyFile(File source, File dest) throws IOException { InputStream is = null; OutputStream os = null; try { is = new FileInputStream(source); os = new FileOutputStream(dest); byte[] buffer = new byte[1024]; int length; while ((length = is.read(buffer)) > 0) { os.write(buffer, 0, length); } } finally { if (is != null) is.close(); if (os != null) os.close(); } } // Given a path check if its part of the Notes or Domino installation public static boolean isNotesDominoPath(String dir) { IPath path = new Path(dir.trim()).addTrailingSeparator(); String[] notesFiles = new String[]{"notes.ini", "nlnotes.exe"}; // $NON-NLS-1$ $NON-NLS-2$ String[] dataFiles = new String[]{"IBM_CredStore", "IBM_TECHNICAL_SUPPORT"}; // $NON-NLS-1$ $NON-NLS-2$ // Go backwards through the path looking for specific files while(true) { if(containsFiles(path.toFile().listFiles(), dataFiles)) { return true; } if(containsFiles(path.toFile().listFiles(), notesFiles)) { return true; } if (path.segmentCount() == 0) { // We've reached the root - bail break; } path = path.removeLastSegments(1); } // Not a Notes/Domino path return false; } private static boolean containsFiles(File[] fileList, String[] files) { for (String file:files) { boolean found = false; for (File f:fileList) { if (StringUtil.equalsIgnoreCase(f.getName(), file)) { found = true; break; } } if (!found) { return false; } } return true; } // Get the first NSF found in a directory public static File getNsfFromDirectory(String directory) { for (File file : new File(directory).listFiles()) { if (file.getName().toLowerCase().endsWith((".nsf"))) { // $NON-NLS-1$ return file; } } return null; } // Given a file return the corresponding XPage if any public static String getXPageName(IFile file) { try { IDesignElement desEl = DominoResourcesPlugin.getDesignElement(file); if((desEl != null) && desEl.getMetaModelID().equals(IMetaModelConstants.XSPPAGES)) { return file.getName(); } } catch (CoreException e) { if (BluemixLogger.BLUEMIX_LOGGER.isErrorEnabled()) { BluemixLogger.BLUEMIX_LOGGER.errorp(BluemixUtil.class, "getXPageName", e, "Failed to get design element"); // $NON-NLS-1$ $NLE-BluemixUtil.Failedtogetdesignelement-2$ } } return null; } // Given an editorPart return the Designer project public static IDominoDesignerProject getDominoDesignerProject (IEditorPart editorPart) { if ( editorPart != null ) { if ( editorPart.getEditorInput() instanceof IFileEditorInput ) { IFileEditorInput file = (IFileEditorInput)editorPart.getEditorInput(); IProject prj = file.getFile().getProject(); try { IDominoDesignerProject desPrj = DominoResourcesPlugin.getDominoDesignerProject(prj); return desPrj; } catch (NsfException e) { if (BluemixLogger.BLUEMIX_LOGGER.isErrorEnabled()) { BluemixLogger.BLUEMIX_LOGGER.errorp(BluemixUtil.class, "getDominoDesignerProject", e, "Failed to get Domino Designer Project"); // $NON-NLS-1$ $NLE-BluemixUtil.FailedtogetDominoDesignerProject-2$ } } } if (editorPart instanceof ManifestMultiPageEditor) { return ((ManifestMultiPageEditor)editorPart).getDesignerProject(); } } return null; } // Given an NSF name return the Designer project if any public static DominoDesignerProject getDesignerProjectFromWorkspace(String nsfName) { IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); if (root != null) { IProject[] projects = root.getProjects(); for (int i = 0; i < projects.length; i++) { try { DominoDesignerProject ddp = (DominoDesignerProject)DominoResourcesPlugin.getDominoDesignerProject(projects[i]); if (ddp != null) { String path = ddp.getNsfPath(); if (StringUtil.equalsIgnoreCase(path, nsfName)) { return ddp; } } } catch (NsfException e) { if (BluemixLogger.BLUEMIX_LOGGER.isErrorEnabled()) { BluemixLogger.BLUEMIX_LOGGER.errorp(BluemixUtil.class, "getDesignerProjectFromWorkspace", e, "Failed to get Domino Designer Project"); // $NON-NLS-1$ $NLE-BluemixUtil.FailedtogetDominoDesignerProject-2$ } } } } return null; } // Write a properties file public static void writeProperties(Properties props, IPath path) { File file = new File(path.toOSString()); FileOutputStream os = null; try { os = new FileOutputStream(file); props.store(os, null); } catch (Exception e) { if (BluemixLogger.BLUEMIX_LOGGER.isErrorEnabled()) { BluemixLogger.BLUEMIX_LOGGER.errorp(BluemixUtil.class, "writeProperties", e, "Failed to write properties {0}", file); // $NON-NLS-1$ $NLE-BluemixUtil.Failedtowriteproperties0-2$ } } finally { if (os != null) { try { os.close(); } catch (IOException e) { if (BluemixLogger.BLUEMIX_LOGGER.isErrorEnabled()) { BluemixLogger.BLUEMIX_LOGGER.errorp(BluemixUtil.class, "writeProperties", e, "Error closing os {0}", file); // $NLE-BluemixUtil.Errorclosingos0-2$ $NON-NLS-1$ } } } } } // Read a properties file public static void readProperties(Properties props, IPath path) { File file = new File(path.toOSString()); props.clear(); if (file.exists()) { FileInputStream is = null; try { is = new FileInputStream(file); props.load(is); } catch (Exception e) { if (BluemixLogger.BLUEMIX_LOGGER.isErrorEnabled()) { BluemixLogger.BLUEMIX_LOGGER.errorp(BluemixUtil.class, "readProperties", e, "Failed to read properties {0}", file); // $NON-NLS-1$ $NLE-BluemixUtil.Failedtoreadproperties0-2$ } } finally { if (is != null) { try { is.close(); } catch (IOException e) { if (BluemixLogger.BLUEMIX_LOGGER.isErrorEnabled()) { BluemixLogger.BLUEMIX_LOGGER.errorp(BluemixUtil.class, "readProperties", e, "Error closing is {0}", file); // $NON-NLS-1$ $NLE-BluemixUtil.Errorclosingis0-2$ } } } } } } // Replace a product tag in a String public static String productizeString(String str) { if(StringUtil.isNotEmpty(str)) { return str.replaceAll("%BM_PRODUCT%", "IBM Bluemix"); // $NLX-BluemixUtil.IBMBluemix-2$ $NON-NLS-1$ } return str; } // Creates a complete local copy of a db with a different replicaID public static String createLocalDatabaseCopy(Database db, String destDbName) throws Throwable { Database newDb = null; String newDbPath = null; try { // Make a copy of the database newDb = db.createCopy(null, destDbName); newDbPath = newDb.getFilePath(); // Copy all the docs DocumentCollection col = db.getAllDocuments(); Document doc = col.getFirstDocument(); while (doc != null) { doc.copyToDatabase(newDb); doc = col.getNextDocument(); } // Copy the profile docs col = db.getProfileDocCollection(null); doc = col.getFirstDocument(); while (doc != null) { doc.copyToDatabase(newDb); doc = col.getNextDocument(); } } finally { if (newDb != null) { try { // Ensure db is flushed to disk newDb.recycle(); // Add a pause for safety, just in case another thread handles the flush Thread.sleep(1000); } catch (NotesException e) { if (BluemixLogger.BLUEMIX_LOGGER.isErrorEnabled()) { BluemixLogger.BLUEMIX_LOGGER.errorp(null, "createLocalDatabaseCopy", e, "Failed to recycle newDb"); // $NON-NLS-1$ $NLE-BluemixUtil.FailedtorecyclenewDb-2$ } } } } return newDbPath; } // Creates a local replica of a db public static String createLocalDatabaseReplica(Database db, String destDbName) throws Throwable { Database newDb = null; String newDbPath = null; try { // Make a replica of the database newDb = db.createReplica(null, destDbName); newDbPath = newDb.getFilePath(); } finally { if (newDb != null) { try { // Ensure db is flushed to disk newDb.recycle(); // Add a pause for safety, just in case another thread handles the flush Thread.sleep(1000); } catch (NotesException e) { if (BluemixLogger.BLUEMIX_LOGGER.isErrorEnabled()) { BluemixLogger.BLUEMIX_LOGGER.errorp(null, "createLocalDatabaseReplica", e, "Failed to recycle newDb"); // $NON-NLS-1$ $NLE-BluemixUtil.FailedtorecyclenewDb.1-2$ } } } } return newDbPath; } public static boolean validateDominoServerName(String serverName, boolean allowEmpty) { if (StringUtil.isEmpty(serverName)) { return allowEmpty; } if (!serverName.contains("/")) { return false; } if ((serverName.charAt(0) == '/') || (serverName.charAt(serverName.length()-1) == '/')) { return false; } return true; } public static boolean validateAddress(String address) { try { InetAddress.getByName(address); } catch (Exception e) { if (BluemixLogger.BLUEMIX_LOGGER.isWarnEnabled()) { BluemixLogger.BLUEMIX_LOGGER.warnp(null, "validateAddress", e, "Failed to resolve \"{0}\"", address); // $NON-NLS-1$ $NLW-BluemixUtil.Failedtoresolve0-2$ } return false; } return true; } // Check for Defect187654 exception - retrieving non string env vars public static boolean isDefect187654Exception(Exception e) { if (e instanceof ClassCastException) { if (e.getStackTrace().length > 0) { if (StringUtil.equalsIgnoreCase(e.getStackTrace()[0].getClassName(), "org.cloudfoundry.client.lib.domain.CloudApplication") && // $NON-NLS-1$ StringUtil.equalsIgnoreCase(e.getStackTrace()[0].getMethodName(), "setEnv")) { // $NON-NLS-1$ return true; } } } return false; } public static String launchChooseFileDialog(String file, String[] filterExts, String[] filterNames) { FileDialog dlg = new FileDialog(Display.getCurrent().getActiveShell()); dlg.setFileName(file); dlg.setText("Choose file"); // $NLX-BluemixUtil.Choosefile-1$ dlg.setFilterExtensions(filterExts); dlg.setFilterNames(filterNames); return dlg.open(); } }