Package com.salesforce.ide.core.internal.utils

Source Code of com.salesforce.ide.core.internal.utils.Utils

/*******************************************************************************
* Copyright (c) 2014 Salesforce.com, inc..
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     Salesforce.com, inc. - initial API and implementation
******************************************************************************/
package com.salesforce.ide.core.internal.utils;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Pattern;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.log4j.Logger;
import org.apache.xerces.parsers.DOMParser;
import org.eclipse.core.internal.resources.OS;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.resources.ResourceAttributes;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.WorkbenchException;
import org.osgi.framework.Bundle;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;

import com.salesforce.ide.api.metadata.types.MetadataExt;
import com.salesforce.ide.core.ForceIdeCorePlugin;
import com.salesforce.ide.core.internal.utils.TestContext.TestContextEnum;
import com.salesforce.ide.core.model.Component;
import com.salesforce.ide.core.services.PackageDeployService;
import com.salesforce.ide.core.services.PackageRetrieveService;
import com.sforce.soap.metadata.FileProperties;
import com.sforce.soap.metadata.ManageableState;
import com.sforce.soap.partner.fault.wsc.ApiFault;

/**
* Common utilities methods
*/
@SuppressWarnings("restriction")
public class Utils {
  private static final Logger logger = Logger.getLogger(Utils.class);

  public static final String DIALOG_TITLE_ERROR = "Error";
  public static final String DIALOG_TITLE_WARNING = "Warning";
  public static final String TEST_CONTEXT_PROP = "TestContext";

  public static boolean isEmpty(Object obj) {
    return obj == null;
  }

  public static boolean isNotEmpty(Object obj) {
    return !isEmpty(obj);
  }

  public static boolean isEmpty(Object[] objs) {
    return objs == null || objs.length == 0;
  }

  public static boolean isNotEmpty(Object[] objs) {
    return !isEmpty(objs);
  }

  public static boolean isEmpty(byte[] objs) {
    return objs == null || objs.length == 0;
  }

  public static boolean isNotEmpty(byte[] objs) {
    return !isEmpty(objs);
  }

  public static boolean isEmpty(Collection<?> col) {
    return col == null || col.isEmpty();
  }

  public static boolean isNotEmpty(Collection<?> col) {
    return !isEmpty(col);
  }

  public static boolean isEmpty(List<?> col) {
    return col == null || col.isEmpty();
  }

  public static boolean isNotEmpty(List<?> col) {
    return !isEmpty(col);
  }

  public static boolean isEmpty(Map<?, ?> map) {
    return map == null || map.isEmpty();
  }

  public static boolean isNotEmpty(Map<?, ?> map) {
    return map != null && !map.isEmpty();
  }

  public static boolean isWorkspaceCaseSensitive() {
    return Platform.OS_MACOSX.equals(Platform.getOS()) ? false
        : new java.io.File("a").compareTo(new java.io.File("A")) != 0;
  }

  public static void openForcePerspective() {
    IWorkbench workbench = ForceIdeCorePlugin.getDefault().getWorkbench();
    IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
    IWorkbenchPage page = window.getActivePage();
    IAdaptable input;

    if (page != null) {
      input = page.getInput();
    } else {
      input = ResourcesPlugin.getWorkspace().getRoot();
    }

    try {
      workbench.showPerspective(Constants.FORCE_PLUGIN_PREFIX
          + ".perspective", window, input);
    } catch (WorkbenchException e) {
      logger.error("Unable to open Force.com Perspective", e);
    }
  }

  public static Shell getShell() {
    Shell shell = PlatformUI.getWorkbench().getWorkbenchWindows()[0]
        .getShell();
    return shell;
  }

  public static void openError(Exception e, String message, String details) {
    IStatus status = new Status(IStatus.ERROR, ForceIdeCorePlugin
        .getPluginId(), Constants.ERROR_CODE__44, details, e);
    ErrorDialog.openError(getShell(), DIALOG_TITLE_ERROR, message, status);
  }

  public static void openError(Throwable pThrowable,
      boolean includeStackTrace, String messageSummary) {
    IStatus status = null;
    messageSummary = Utils.isEmpty(messageSummary) ? ForceExceptionUtils
        .getRootExceptionMessage(pThrowable) : messageSummary;
    if (includeStackTrace && logger.isDebugEnabled()) {
      status = new MultiStatus(ForceIdeCorePlugin.getPluginId(),
          Constants.ERROR_CODE__44, getStatusMessage(pThrowable),
          ForceExceptionUtils.getRootCause(pThrowable));
      addTraceToStatus((MultiStatus) status, pThrowable.getStackTrace(),
          IStatus.ERROR);
    } else {
      status = new Status(IStatus.ERROR,
          ForceIdeCorePlugin.getPluginId(), Constants.ERROR_CODE__44,
          getStatusMessage(pThrowable), null);
    }
    openErrorDialog(DIALOG_TITLE_ERROR, messageSummary, status);
  }

  public static void openError(Shell shell, Throwable pThrowable,
      boolean includeStackTrace, String messageSummary) {
    IStatus status = null;
    messageSummary = Utils.isEmpty(messageSummary) ? ForceExceptionUtils
        .getRootCause(pThrowable).getMessage() : messageSummary;
    if (includeStackTrace && logger.isDebugEnabled()) {
      status = new MultiStatus(ForceIdeCorePlugin.getPluginId(),
          Constants.ERROR_CODE__44, getStatusMessage(pThrowable),
          ForceExceptionUtils.getRootCause(pThrowable));
      addTraceToStatus((MultiStatus) status, pThrowable.getStackTrace(),
          IStatus.ERROR);
    } else {
      status = new Status(IStatus.ERROR,
          ForceIdeCorePlugin.getPluginId(), Constants.ERROR_CODE__44,
          getStatusMessage(pThrowable), null);
    }
    openErrorDialog(shell, DIALOG_TITLE_ERROR, messageSummary, status);
  }

  public static void openWarning(Throwable pThrowable,
      boolean includeStackTrace, String messageSummary) {
    IStatus status = null;
    if (includeStackTrace && logger.isDebugEnabled()) {
      status = new MultiStatus(ForceIdeCorePlugin.getPluginId(),
          Constants.ERROR_CODE__44, getStatusMessage(pThrowable),
          ForceExceptionUtils.getRootCause(pThrowable));
      addTraceToStatus((MultiStatus) status, pThrowable.getStackTrace(),
          IStatus.WARNING);
    } else {
      status = new Status(IStatus.WARNING, ForceIdeCorePlugin
          .getPluginId(), Constants.ERROR_CODE__44,
          getStatusMessage(pThrowable), null);
    }
    openErrorDialog(DIALOG_TITLE_WARNING, messageSummary, status);
  }

  private static String getStatusMessage(Throwable th) {
    if (th == null) {
      return null;
    }

    if (th instanceof ApiFault) {
      ApiFault apiFault = (ApiFault) th;
      return apiFault.getExceptionCode().name() + " - "
          + apiFault.getExceptionMessage();
    } else if (th.getCause() instanceof ApiFault) {
      ApiFault apiFault = (ApiFault) th.getCause();
      return apiFault.getExceptionCode().name() + " - "
          + apiFault.getExceptionMessage();
    } else {
      return ForceExceptionUtils.getStrippedRootCauseMessage(th);
    }
  }

  private static void openErrorDialog(String type, String message,
      IStatus status) {
    Shell newShell = getShell();
    if (newShell == null) {
      newShell = new Shell();
    }
    ErrorDialog.openError(newShell, type, message, status);
  }

  private static void openErrorDialog(Shell shell, String type,
      String message, IStatus status) {
    ErrorDialog.openError(shell, type, message, status);
  }

  public static void addTraceToStatus(MultiStatus multiStatus,
      StackTraceElement[] trace, int errorCode) {
    for (int i = 1; i < trace.length; i++) {
      IStatus stat = new Status(errorCode, ForceIdeCorePlugin
          .getPluginId(), Constants.ERROR_CODE__44, trace[i]
          .getClassName()
          + "."
          + trace[i].getMethodName()
          + " ("
          + trace[i].getFileName()
          + " "
          + trace[i].getLineNumber()
          + ")", null);
      multiStatus.add(stat);
    }
  }

  public static String generateCoreExceptionLog(CoreException ex) {
    if(ex==null){
      throw new IllegalArgumentException();
    }

    StringBuffer strBuff = new StringBuffer(ex.getMessage());
    if (ex.getStatus() != null
        && ex.getStatus().isMultiStatus()
        && isNotEmpty(((MultiStatus) ex.getStatus()).getChildren())) {
      strBuff.append(" Cause(s):\n");
      IStatus[] stats = ((MultiStatus) ex.getStatus()).getChildren();
      int cnt = 0;
      for (IStatus status : stats) {
        strBuff.append(" (").append(++cnt).append(") ").append(
            status.getMessage());
        if (status.getException() != null) {
          strBuff.append("\n    Root Exception: ").append(
              status.getException().getMessage());
        }
      }

    } else if (ex.getStatus() != null) {
      strBuff.append(" Cause:\n");
      strBuff.append(" (1) ").append(ex.getStatus().getMessage());
      if (ex.getStatus().getException() != null) {
        strBuff.append("\n    Root Exception: ").append(
            ex.getStatus().getException().getMessage());
      }

    }
    return strBuff.toString();
  }

  public static boolean openConfirm(String pTitle, String pMessage) {
    return MessageDialog.openConfirm(getShell(), pTitle, pMessage);
  }

  public static boolean openConfirm(Shell shell, String pTitle,
      String pMessage) {
    return MessageDialog.openConfirm(shell, pTitle, pMessage);
  }

  public static boolean openQuestion(String pTitle, String pMessage) {
    return MessageDialog.openQuestion(getShell(), pTitle, pMessage);
  }

  public static boolean openQuestion(Shell shell, String pTitle,
      String pMessage) {
    return MessageDialog.openQuestion(shell, pTitle, pMessage);
  }

  public static void openError(String pTitle, String pMessage) {
    MessageDialog.openError(getShell(), pTitle, pMessage);
  }

  public static void openInfo(String pTitle, String pMessage) {
    MessageDialog.openInformation(getShell(), pTitle, pMessage);
  }

  public static void openWarn(String pTitle, String pMessage) {
    MessageDialog.openWarning(getShell(), pTitle, pMessage);
  }

  public static void openWarn(Shell shell, String pTitle, String pMessage) {
    MessageDialog.openWarning(shell, pTitle, pMessage);
  }

  public static void openDialog(IProject project, WizardDialog dialog) {
    TestContext testContext = TestContext
        .getTestContextBy(getTestContextEnum(project));
    testContext.execAsyncRunnables();
    dialog.open();
  }

  public static boolean openQuestion(IProject project, Shell shell,
      String title, String message) {
    TestContext testContext = TestContext
        .getTestContextBy(getTestContextEnum(project));
    testContext.execAsyncRunnables();
    return openQuestion(shell, title, message);
  }

  public static IResource getCurrentSelectionResource() {
    IWorkbenchWindow workbenchWindow = ForceIdeCorePlugin.getDefault()
        .getWorkbench().getActiveWorkbenchWindow();
    if (workbenchWindow == null) {
      return null;
    }

    ISelection selection = workbenchWindow.getSelectionService()
        .getSelection();
    if (selection instanceof IStructuredSelection) {
      Object firstSelected = ((IStructuredSelection) selection)
          .getFirstElement();
      if (firstSelected instanceof IResource) {
        return (IResource) firstSelected;
      }
    }
    return null;
  }

  public static IStatus getStatus(Exception e) {
    String msg = e.getMessage();
    if (e instanceof CoreException) {
      CoreException ce = (CoreException) e;
      IStatus status = ce.getStatus();
      return status;
    }
    IStatus status = new Status(IStatus.ERROR, ForceIdeCorePlugin
        .getPluginId(), IStatus.OK, msg, null);
    return status;
  }

  public static String getDisplayDate(Calendar cal) {
    if (cal == null) {
      return "n/a";
    }
    SimpleDateFormat formatter = new SimpleDateFormat(
        "E yyyy.MM.dd 'at' hh:mm:ss a zzz");
    return formatter.format(cal.getTime());
  }

  public static void sleep(int millis) {
    try {
      Thread.sleep(millis);
    } catch (InterruptedException e) {
    }
  }

  public static boolean isValidFullUrl(String endpoint) {
    if (Utils.isEmpty(endpoint)) {
      return false;
    }

    try {
      new URL(endpoint);
    } catch (MalformedURLException e) {
      return false;
    }

    return true;
  }

  public static boolean validateDomainName(String domainName) {
    String oneAlpha = "(.)*((\\p{Alpha})|[-])(.)*";
    String domainIdentifier = "((\\p{Alnum})([-]|(\\p{Alnum}))*(\\p{Alnum}))|(\\p{Alnum})";
    String domainNameRule = "(" + domainIdentifier + ")((\\.)("
        + domainIdentifier + "))*";
    if (domainName == null || domainName.length() > 63) {
      return false;
    }
    return domainName.matches(domainNameRule)
        && domainName.matches(oneAlpha);
  }

  public static String getServerNameFromUrl(String url) {
    if (Utils.isEmpty(url)) {
      return url;
    }

    String protocol = (url.startsWith(Constants.HTTPS) ? Constants.HTTPS
        : Constants.HTTP)
        + "://";
    return url.substring(url.indexOf(protocol) + protocol.length(), url
        .indexOf("/", protocol.length() + 1));
  }

  public static boolean isInternalMode() {
    String mode = System.getProperty(Constants.SYS_SETTING_SFDC_INTERNAL);
    return Utils.isNotEmpty(mode)
        && Constants.SYS_SETTING_SFDC_INTERNAL_VALUE.equals(mode) ? true : false;
  }

  public static String getDefaultSystemApiVersion() {
    String apiVersion = System
        .getProperty(Constants.SYS_SETTING_DEFAULT_API_VERSION);
    return Utils.isNotEmpty(apiVersion) ? apiVersion : Constants.EMPTY_STRING;
  }

  public static String getPollLimit() {
    String pollLimit = System
        .getProperty(Constants.SYS_SETTING_POLL_LIMIT_MILLIS);
    return Utils.isNotEmpty(pollLimit) ? pollLimit : Constants.EMPTY_STRING;
  }

  public static String getLocaleFormattedDateTime(long datetime) {
    return DateFormat.getDateTimeInstance(DateFormat.SHORT,
        DateFormat.MEDIUM, Locale.getDefault()).format(
        new Date(datetime));
  }

  public static String getCurrentFormattedDateTime() {
    return (new SimpleDateFormat(Constants.STANDARD_DATE_FORMAT))
        .format(new Date());
  }

  public static String getFormattedTimestamp(File file) {
    return file != null && file.exists() ? getLocaleFormattedDateTime(file.lastModified()) : null;
  }

  public static File getCacheFile(IProject project) {
    try {
      Bundle bundle = ForceIdeCorePlugin.getDefault().getBundle();
      IPath state = null;
      if (project != null) {
        state = project.getWorkingLocation(ForceIdeCorePlugin
            .getPluginId());
      } else {
        state = Platform.getStateLocation(bundle);
      }

      return new File(state.toFile(), Constants.CACHE_FILENAME);
    } catch (Exception e) {
      logger.warn("Unable to get cache file: " + e.getMessage());
    }
    return null;
  }

  public static URL getCacheUrl(IProject project) {
    File file = Utils.getCacheFile(project);
    if (file != null) {
      try {
        if (logger.isDebugEnabled()) {
          logger.debug("Manifest cache file (does"
              + (file.exists() ? " " : " not ") + "exist): "
              + file.toURL().toExternalForm());
        }

        return file.toURL();
      } catch (MalformedURLException e) {
        logger.warn("Unable to get url from file: " + e.getMessage());
      }
    }

    if (logger.isInfoEnabled()) {
      logger.info("Manifest cache file: n/a");
    }

    return null;
  }

  public static boolean isDebugMode() {
    String debug = System.getProperty(Constants.SYS_SETTING_DEBUG);
    return logger != null && logger.isDebugEnabled()
        || Utils.isNotEmpty(debug)
        && Constants.SYS_SETTING_DEBUG_VALUE.equals(debug);
  }

  public static boolean isManifestListenerEnabled() {
    String listener = System
        .getProperty(Constants.SYS_SETTING_MANIFEST_LISTENER);
    return Utils.isNotEmpty(listener) ? Boolean.parseBoolean(listener)
        : true;
  }

  public static boolean hasDefaultProperties() {
    String propFilePath = System
        .getProperty(Constants.SYS_SETTING_PROPERTIES);
    return Utils.isNotEmpty(propFilePath)
        && (new java.io.File(propFilePath)).exists();
  }

  public static Properties getDefaultProperties() {
    Properties props = null;
    String propFilePath = System
        .getProperty(Constants.SYS_SETTING_PROPERTIES);
    if (Utils.isEmpty(propFilePath)) {
      return props;
    }

    java.io.File propFile = new java.io.File(propFilePath);
    if (!propFile.exists()) {
      return props;
    }

    FileInputStream fis = null;
    try {
      fis = new FileInputStream(propFile);
      if (fis.available() > 0) {
        logger.debug("Loading properties found in prop file '"
            + propFilePath + "'");
        props = new Properties();
        props.load(fis);
      } else {
        logger.debug("No content found in prop file '" + propFilePath
            + "'");
      }

    } catch (Exception e) {
      logger.warn("Unable to load prop file '" + propFilePath + "'", e);
    } finally {
      if (fis != null) {
        try {
          fis.close();
        } catch (IOException e) {
          logger.error("Unable to close stream");
        }
      }
    }

    return props;
  }

  /**
   * remove service level version number from bundle version which composed by
   * <major_version_#>.<minor_version_#>.<service_level_version_#>.qualifier
   *
   * @param bundleVersion
   * @return
   */
  public static String removeServiceLevelFromPluginVersion(
      String bundleVersion) {
    String[] subBundleVersion = bundleVersion.split("\\.");
    StringBuffer strBuffer = new StringBuffer();
    for (int i = 0; i < subBundleVersion.length; i++) {
      if (i == 2) {
        continue; // skip service level version
      }
      strBuffer.append(subBundleVersion[i]).append(".");
    }
    String newBundleVersion = strBuffer.toString();
    return newBundleVersion.substring(0, newBundleVersion.length() - 1);
  }

  public static void logStats() {
    OperationStats[] operationsStats = new OperationStats[2];
    OperationStats aggregatedStats = new OperationStats(
        OperationStats.AGGREGATED_OPERATIONS);

    int idx = 0;
    if (PackageDeployService.getOperationStats() != null) {
      PackageDeployService.getOperationStats().logStats();
      operationsStats[idx] = PackageDeployService.getOperationStats();
    }

    if (PackageRetrieveService.getOperationStats() != null) {
      PackageRetrieveService.getOperationStats().logStats();
      operationsStats[++idx] = PackageRetrieveService.getOperationStats();
    }

    if (isNotEmpty(operationsStats)) {
      aggregatedStats.aggregateStats(operationsStats);
      aggregatedStats.logStats();
    }

    ForceIdeCorePlugin.logStats();

  }

  public static String timeoutToSecs(String timeout) {
    return timeoutToSecs(Long.parseLong(timeout));
  }

  public static String timeoutToSecs(long timeout) {
    return timeout < 1 ? "0 secs" : timeout / Constants.SECONDS_TO_MILISECONDS + " secs";
  }

  // REVIEWME: should this be moved to ProjectService?
  public static TestContextEnum getTestContextEnum(IProject project) {
    if (project == null) {
      return TestContextEnum.NONE;
    }
    IEclipsePreferences node = getPreferences(project);
    return node != null ? TestContextEnum.valueOf(node.get(TEST_CONTEXT_PROP,
        TestContextEnum.NONE.toString())) : TestContextEnum.NONE;
  }

  public static IEclipsePreferences getPreferences(IProject project) {
    if (project == null) {
      return null;
    }
    ProjectScope projectScope = new ProjectScope(project);
    IEclipsePreferences node = projectScope
        .getNode(Constants.PLUGIN_PREFIX);
    return node;
  }

  public static Method getGetter(Class<?> clazz, String field) {
    if (clazz == null) {
      return null;
    }

    Method[] methods = clazz.getDeclaredMethods();
    if (isEmpty(methods)) {
      return null;
    }

    for (Method method : methods) {
      if (Utils.isNotEmpty(field) && method.getName().startsWith("get"+field) && method.getGenericParameterTypes().length==0) {
        return method;
      }
    }

    return null;
  }

  public static List<String> getProperties(Class<?> clazz) {
    if (clazz == null) {
      return null;
    }

    List<String> properties = new ArrayList<String>();
    Method[] methods = clazz.getDeclaredMethods();
    if (isNotEmpty(methods)) {
      for (int i = 0; i < methods.length; i++) {
        Method method = methods[i];
        if (method.getName().startsWith("get")
            && method.getGenericParameterTypes().length == 0) {
          properties.add(method.getName().substring(3));
        }
      }
    }

    return properties;
  }

  public static Object getPropertyValue(Object obj, String propertyName)
      throws ClassNotFoundException, IllegalArgumentException,
      IllegalAccessException, InvocationTargetException {
    if (obj == null || propertyName == null) {
      return null;
    }

    Object propertyValue = null;
    Method getterMethod = getGetterMethod(obj.getClass(), propertyName);
    if (getterMethod != null) {
      Object[] args = null;
      propertyValue = getterMethod.invoke(obj, args);
    }
    return propertyValue;
  }

  public static Method getGetterMethod(Class<?> clazz, String methodNameWithoutGetPrefix)
      throws ClassNotFoundException {
    Method getterMethod = null;
    Method[] methods = clazz.getDeclaredMethods();
    if (isNotEmpty(methods)) {
      for (Method method : methods) {
        if (method.getName().equals("get" + methodNameWithoutGetPrefix) && method.getGenericParameterTypes().length==0) {
          getterMethod = method;
          break;
        }
      }
    }
    return getterMethod;
  }

  @SuppressWarnings("unchecked")
  public static Class<? extends MetadataExt> getMetadataClassForComponentType(
      String componentType) throws ClassNotFoundException {
    if (Utils.isEmpty(componentType)) {
      return null;
    }

    return (Class<? extends MetadataExt>) Class
        .forName(Constants.COMPONENT_TYPE_API_CLASS_PACKAGE + "."
            + componentType);
  }

  public static void saveDocument(Document doc, Bundle bundle, String fileName)
      throws IOException, TransformerException {
    IPath state = Platform.getStateLocation(bundle);
    saveDocument(doc, state.toPortableString() + File.separator + fileName);
  }

  public static void saveDocument(Document doc, String fullPath)
      throws IOException, TransformerException {
    File f = new File(fullPath);
    f.createNewFile();

    TransformerFactory tfactory = TransformerFactory.newInstance();
    tfactory.setAttribute("indent-number", new Integer(2));
    Transformer xform = tfactory.newTransformer();
    xform.setOutputProperty(OutputKeys.INDENT, "yes");
    // xform.setOutputProperty("{http://xml.apache.org/xslt}indent-amount",
    // "4");
    Source src = new DOMSource(doc);

    FileOutputStream stream = new FileOutputStream(f, false);
    OutputStreamWriter writer = new OutputStreamWriter(stream,
        Constants.FORCE_DEFAULT_ENCODING_CHARSET);
    Result result = new StreamResult(writer);
    xform.transform(src, result);
    writer.close();
  }

  public static Document loadDocument(URL fileUrl) {
    Document doc = null;
    DOMParser parser = new DOMParser();

    if (logger.isDebugEnabled()) {
      logger.debug("Loading document from " + fileUrl.toExternalForm());
    }

    try {
      InputSource inputSource = new InputSource(fileUrl.openStream());
      parser.parse(inputSource);
      doc = parser.getDocument();
    } catch (Exception e) {
      logger.warn("Unable to load document: " + e.getMessage());
    }

    return doc;
  }

  public static void adjustResourceReadOnly(IResource resource,
      boolean readyOnly, boolean recursive) {
    if (resource == null || !resource.exists()) {
      return;
    }

    // no need to set read-only if resource is already set to desired
    // read-only setting
    if (resource.getResourceAttributes() != null
        && resource.getResourceAttributes().isReadOnly() != readyOnly) {
      ResourceAttributes resourceAttributes = new ResourceAttributes();
      resourceAttributes.setReadOnly(readyOnly);
      try {
        resource.setResourceAttributes(resourceAttributes);
        if (logger.isDebugEnabled()) {
          logger.debug("Set resource '"
              + resource.getProjectRelativePath()
                  .toPortableString() + "' read-only="
              + readyOnly);
        }
      } catch (CoreException e) {
        String logMessage = Utils.generateCoreExceptionLog(e);
        logger.warn("Unable to set read-only attribute on file "
            + resource.getName() + ": " + logMessage);
      }
    }

    if (recursive && resource instanceof IContainer) {
      try {
        IResource[] children = ((IContainer) resource).members();
        if (Utils.isNotEmpty(children)) {
          for (IResource childResource : children) {
            adjustResourceReadOnly(childResource, readyOnly,
                recursive);
          }
        }
      } catch (CoreException e) {
        String logMessage = Utils.generateCoreExceptionLog(e);
        logger.warn("Unable to get children for folder "
            + resource.getName() + ": " + logMessage);
      }
    }
  }

  // !!! ADD NEW METHODS ABOVE THE FOLLOWING STRING UTILS SECTION !!!

  // (S T A R T) M O V E T O S T R I N G U T I L S
  private final static String[] IDE_INVALID_CHARS = new String[] { ">", "<",
      ",", ":", ";", "/", "\\" };
  private final static String[] HOST_PORT_INVALID_CHARS = new String[] { ">",
      "<", ",", ";", "/", "\\", " " };

  public static boolean isEqual(String str, String str2,boolean isCaseSensitive) {
    return isNotEmpty(str) && isNotEmpty(str2) ? isCaseSensitive ? str.equals(str2) : str.equalsIgnoreCase(str2) : false;
  }

  public static boolean isEqual(String str, String compareStr) {
    return isNotEmpty(str) && isNotEmpty(compareStr)
        && str.equals(compareStr);
  }

  public static boolean isNotEqual(String str, String str2) {
    return !isEqual(str, str2, true);
  }

  public static boolean isEmpty(String str) {
    return str == null || str.length() == 0;
  }

  public static boolean isNotEmpty(String str) {
    return !isEmpty(str);
  }

  public static boolean startsWith(String str, String suffix) {
    return isNotEmpty(str) && isNotEmpty(suffix) && str.startsWith(suffix);
  }

  public static boolean endsWith(String str, String suffix) {
    return isNotEmpty(str) && isNotEmpty(suffix) && str.endsWith(suffix);
  }

  public static boolean contains(String str, String contains) {
    return isNotEmpty(str) && isNotEmpty(contains)
        && str.contains(contains);
  }

  public static InputStream openContentStream(String contents) {
    return new ByteArrayInputStream(contents.getBytes());
  }

  public static String getContentString(IFile file) throws IOException,
      CoreException {
    String contentStr = null;
    if (file != null && file.exists()) {
      StringBuffer strBuff = new StringBuffer();
      BufferedReader reader = null;
      InputStream contents = null;
      try {
        contents = file.getContents();
        reader = new BufferedReader(new InputStreamReader(contents,
            Constants.UTF_8));
        String line = reader.readLine();
        if (line != null) {
          strBuff.append(line);
        }
        while ((line = reader.readLine()) != null) {
          strBuff.append(Constants.NEW_LINE);
          strBuff.append(line);
        }
      } catch (IOException e) {
        logger.error("Unable to load body from file " + file.getName(),
            e);
        throw e;
      } catch (CoreException e) {
        throw e;
      } finally {
        try {
          if (reader != null) {
            reader.close();
          }
                } catch (IOException e) {}

        try {
          if (contents != null) {
            contents.close();
          }
                } catch (IOException e) {}
      }

      if (logger.isDebugEnabled()) {
        logger.debug("Loaded body size ["
            + strBuff.toString().getBytes().length
            + "] bytes from file '" + file.getName() + "'");
      }

      contentStr = strBuff.toString();
    }

    return contentStr;
  }

  public static String getStringFromStream(InputStream is, long length)
      throws IOException {
    return getStringFromBytes(getBytesFromStream(is, length));
  }

  public static byte[] getBytesFromStream(InputStream is, long length)
      throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
    byte[] buffer = new byte[1024];
    int len;

    while ((len = is.read(buffer)) >= 0) {
      out.write(buffer, 0, len);
    }

    is.close();
    out.close();
    return out.toByteArray();
  }

  public static String getStringFromBytes(byte[] bytes) {
    return new String(bytes);
  }

  public static byte[] getBytesFromFile(File file) throws IOException {
    if (file == null || !file.exists()) {
      return null;
    }

    return getBytesFromStream(new FileInputStream(file), file.length());
  }

  public static byte[] getBytesFromFile(IFile file) throws IOException,
      CoreException {
    if (file == null || !file.exists()) {
      return null;
    }

    return getBytesFromStream(file.getContents(), 0);
  }

  public static String trim(String str) {
    return Utils.isNotEmpty(str) ? str.trim() : str;
  }

  public static String replaceSpaceWithUnderscore(String str) {
    return str.replaceAll(" ", "_");
  }

  public static String stripExtension(Object obj) {
    if (obj == null) {
      return null;
    }

    String tmpName = null;
    if (obj instanceof Component) {
      tmpName = ((Component) obj).getName();
    } else if (obj instanceof IFile) {
      tmpName = ((IFile) obj).getName();
    } else if (obj instanceof String) {
      tmpName = (String) obj;
    }

    if (isNotEmpty(tmpName) && tmpName.contains(".")) {
      tmpName = tmpName.substring(0, tmpName.indexOf("."));
    }

    // strip "-meta" typically found on folder metadata files
    if (isNotEmpty(tmpName) && tmpName.endsWith("-meta")) {
      tmpName = tmpName.substring(0, tmpName.indexOf("-meta"));
    }

    return tmpName;
  }

  public static String stripSourceFolder(String filePath) {
    if (isEmpty(filePath)) {
      return filePath;
    }
    String[] folderPrefixes = new String[] {
        Constants.SOURCE_FOLDER_NAME + "/",
        Constants.REFERENCED_PACKAGE_FOLDER_NAME + "/" };

    for (String folderPrefix : folderPrefixes) {
      if (filePath.startsWith(folderPrefix)) {
        return filePath.substring(filePath.indexOf(folderPrefix)
            + folderPrefix.length());
      }
    }

    return filePath;
  }

  public static String stripNamespace(String str, String namespace) {
    if (isEmpty(namespace) || isEmpty(str)
        || !str.startsWith(namespace + Constants.NAMESPACE_SEPARATOR)) {

      return str;
    }

    if (logger.isDebugEnabled()) {
      logger.debug("Remove prepended namespace '" + namespace
          + "' from '" + str + "'");
    }

    return str.substring(namespace.length()
        + Constants.NAMESPACE_SEPARATOR.length());
  }

  public static String getNameFromFilePath(String filePath) {
    if (isNotEmpty(filePath) && filePath.contains("/")) {
      int idx = filePath.lastIndexOf("/") + 1;
      filePath = filePath.substring(idx);
      if (isNotEmpty(filePath) && filePath.contains(".")) {
        filePath = stripExtension(filePath);
      }
    }
    return filePath;
  }

  public static String getPlural(String str) {
    if (isEmpty(str)) {
      return str;
    }

    if (str.endsWith("x") || str.endsWith("ss")) {
      return str + "es";
    } else if (str.endsWith("s")) {
      return str;
    } else {
      return str + "s";
    }
  }

  public static String stripUnsupportedChars(String str) {
    if (isEmpty(str)) {
      return str;
    }
    return str.replaceAll(":", "");
  }

  public static boolean isAlphaNumericValid(String str) {
    if (isEmpty(str)) {
      return true;
    }
    String regex = "(\\w+)";
    return str.matches(regex);
  }

  /**
   * Metadata names are (where needed) encoded such that they are reasonable
   * file names & do not contain '.'. The basic encoding is URL encoding,
   * excluding '+' (spaces are preserved), but also escaping '.' to '%2E' and
   * '__' to '%5F%5F'
   */
  public static String encode(String name) {
    if (isEmpty(name)) {
      return name;
    }

    try {
      String replaceStr = URLEncoder.encode(name,
          Constants.FORCE_DEFAULT_ENCODING_CHARSET);
      replaceStr = replaceStr.replace('+', ' ');
      // Javadoc of URLEncoder.encode() - The special characters ".", "-",
      // "*", and "_" remain the same.
      // replaceStr = replaceStr.replace(".", "%2E");
      // replaceStr = replaceStr.replace("__", "%5F%5F");

      if (logger.isDebugEnabled() && !name.equals(replaceStr)) {
        logger.debug("Encoded name '" + name + "' to '" + replaceStr
            + "'");
      }

      return replaceStr;
    } catch (UnsupportedEncodingException uee) {
      throw new RuntimeException(uee);
    }
  }

  public static boolean containsInvalidChars(String str) {
    if (isEmpty(str)) {
      return false;
    }

    for (String invalidChar : getInvalidChars()) {
      if (str.contains(invalidChar)) {
        return true;
      }
    }

    return false;
  }

  protected static String[] getInvalidChars() {
    Set<String> invalidCharSet = new HashSet<String>();
    // invalid resource chars provided by eclipse platform
    for (char osInvalidChar : OS.INVALID_RESOURCE_CHARACTERS) {
      invalidCharSet.add(String.valueOf(osInvalidChar));
    }
    // invalid chars defined by IDE
    for (String ideInvalidChar : IDE_INVALID_CHARS) {
      invalidCharSet.add(ideInvalidChar);
    }
    return invalidCharSet.toArray(new String[invalidCharSet.size()]);
  }

  public static boolean containsInvalidHostPortChars(String str) {
    if (isEmpty(str)) {
      return false;
    }

    for (String invalidChar : HOST_PORT_INVALID_CHARS) {
      if (str.contains(invalidChar)) {
        return true;
      }
    }

    return false;
  }

  public static String stripNonAlphaNumericChars(String str) {
    if (isEmpty(str)) {
      return str;
    }
    str = str.replaceAll("[^a-zA-Z0-9 _]", ""); // clean up nonAlphaNumeric
    // char in front/trail of _.
    // Ex. -__a__b__c__- would
    // become __a__b__c__
    str = str.replaceAll("^_*", ""); // strips all starting "_". Ex
    // __a__b__c__ would become
    // a__b__c__
    str = str.replaceAll("_*$", ""); // strips all trailing "_". Ex
    // a__b__c__ would become a__b__c
    str = str.replaceAll("_+", "_"); // replaces all leftover multiple
    // occurances of "_" with 1 "_". Ex.
    // a__b__c would become a_b_c
    return str;
  }

  public static boolean containsNonAlphaNumericChars(String str) {
    if (isEmpty(str)) {
      return false;
    }

    Pattern p = Pattern.compile("[^a-zA-Z0-9]");
    return p.matcher(str).matches();
  }

  public static String generateNameFromLabel(String str) {
    if (isEmpty(str)) {
      return str;
    }

    if (startsWithNumeric(str)) {
      str = "X" + str;
    }

    str = stripNonAlphaNumericChars(str);
    return replaceSpaceWithUnderscore(str);
  }

  public static boolean startsWithNumeric(String str) {
    if (isEmpty(str)) {
      return false;
    }

    Pattern p = Pattern.compile("[0-9].*");
    return p.matcher(str).matches();
  }

  public static String capitalizeFirstLetter(String name) {
    return isNotEmpty(name) ? Character.toUpperCase(name.charAt(0))
        + name.toLowerCase().substring(1) : name;
  }

  /**
   *
   * @param name
   *            - string need to cap first letter and letter after specific
   *            token
   * @param token
   *            - token
   * @param escape
   *            - does this token needs escape?
   * @return
   */
  public static String capFirstLetterAndLetterAfterToken(String name,
      String token, boolean escape) {
    if (name.indexOf(token.toUpperCase()) == -1
        && name.indexOf(token.toLowerCase()) == -1) {
      return capitalizeFirstLetter(name);
    }
    String[] segments = name.toLowerCase().split(
        escape ? "\\" + token : token.toLowerCase()); // escaping .
    StringBuffer sb = new StringBuffer();
    for (String segment : segments) {
      sb = sb.append(capitalizeFirstLetter(segment)).append(
          token.toLowerCase());
    }
    return sb.substring(0, sb.length() - 1);
  }

  public static boolean firstLetterCapitalized(String name) {
    return isNotEmpty(name) ? Character.isUpperCase(name.charAt(0)) : false;
  }

  public static String camelCaseToSpaces(String str) {
    if (isEmpty(str)) {
      return str;
    }

    StringBuffer result = new StringBuffer();
    char prevChar = ' ';

    for (int i = 0; i < str.length(); i++) {
      char c = str.charAt(i);
      if (Character.isUpperCase(c) && !Character.isUpperCase(prevChar)) {
        result.append(' ');
        result.append(Character.toUpperCase(c));
      } else {
        result.append(c);
      }

      prevChar = c;
    }

    return result.toString();
  }

  /**
   * Return null if filePath doesn't have file extension but this method will
   * fail: 1) if filePath param doesn't have valid file extension and having .
   * in filePath 2) if filePath is pointing to folder metadata file See
   * testcase: UtilsTest_unit.testGetExtensionFromFilePath() for usage
   */
  public static String getExtensionFromFilePath(String filePath) {
    if (Utils.isEmpty(filePath)) {
      logger.error("Filepath cannot be null");
      throw new IllegalArgumentException("Filepath cannot be null");
    }

    String fileExtension = null;
    String[] splitFilePath = filePath.split("\\.");
    if (splitFilePath.length == 1) {
      return null; // no extension found!
    }
    if (filePath.endsWith(Constants.DEFAULT_METADATA_FILE_EXTENSION)) {
      // if it's metadata file, file extension should be
      // <component-file-extension>-meta.xml
      fileExtension = splitFilePath[splitFilePath.length - 2]
          + Constants.DOT + splitFilePath[splitFilePath.length - 1];
    } else {
      // if it's regular component file, file extension should very last
      // string append after .
      fileExtension = splitFilePath[splitFilePath.length - 1];
    }
    return fileExtension;

  }

  public static boolean isSkipCompatibilityCheck() {
    String mode = System
        .getProperty(Constants.SYS_SETTING_SKIP_COMPATIBILITY_CHECK);
    return Utils.isNotEmpty(mode)
        && Constants.SYS_SETTING_SKIP_COMPATIBILITY_CHECK_VALUE
            .equals(mode) ? true : false;
  }

  public static boolean isUpgradeEnabled() {
    String mode = System.getProperty(Constants.SYS_SETTING_UPGRADE_ENABLE);
    return Utils.isEmpty(mode) || isEqual("true", mode) ? true : false;
  }

  /**
   * if the input array contains any packaged components, returns a new
   * FileProperties array which lacks any packaged components otherwise just
   * returns the input array
   */

  public static FileProperties[] removePackagedFiles(FileProperties[] props,
      String organizationNamespace) {
    if (Utils.isEmpty(props)) {
      logger
          .debug("Input file properties is empty. Skip remove packaged file check.");
      return props;
    }

    List<FileProperties> newProps = new ArrayList<FileProperties>();

    for (FileProperties prop : props) {
      if (prop.getManageableState() != ManageableState.installed
          && (Utils.isEmpty(prop.getNamespacePrefix()) || prop
              .getNamespacePrefix().equals(organizationNamespace))) {
        newProps.add(prop);
      }

      else if (logger.isDebugEnabled()) {
        logger.debug(prop.getFullName()
            + " removed from FileProperties"); //$NON-NLS-1$
      }
    }

    if (newProps.size() != props.length) {
      return newProps.toArray(new FileProperties[newProps.size()]);
    }

    return props;
  }

  public static String replaceColonToSurroundingGenericBlock(String type) {
    return type.indexOf(":") > -1 ? type.replace(":", "<") + ">" : type; // replace
    // List:@KeyType
    // to
    // List<@KeyType>
  }

  public static String recursiveReplaceAll(String str, String regex,
      String replacement) {
    String replaced = str.replaceAll(regex, replacement);
    boolean flag = true;
    while (flag) {
      String replaced_again = replaced.replaceAll(regex, replacement);
      if (replaced.equalsIgnoreCase(replaced_again)) {
        flag = false;
      } else {
        replaced = replaced_again;
      }
    }
    return replaced;
  }
}
TOP

Related Classes of com.salesforce.ide.core.internal.utils.Utils

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.