Package com.google.enterprise.connector.sharepoint.client

Source Code of com.google.enterprise.connector.sharepoint.client.Util

// Copyright 2007 Google Inc.
//
// 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.google.enterprise.connector.sharepoint.client;

import static com.google.enterprise.connector.spi.SpiConstants.CaseSensitivityType.EVERYTHING_CASE_INSENSITIVE;
import static com.google.enterprise.connector.spi.SpiConstants.PrincipalType.UNQUALIFIED;

import com.google.common.base.Strings;
import com.google.enterprise.connector.sharepoint.client.SPConstants.FeedType;
import com.google.enterprise.connector.sharepoint.wsclient.client.BaseWS;
import com.google.enterprise.connector.spi.Principal;
import com.google.enterprise.connector.spi.RepositoryException;

import org.apache.axis.AxisFault;

import org.joda.time.Chronology;
import org.joda.time.DateTime;
import org.joda.time.convert.ConverterManager;
import org.joda.time.convert.InstantConverter;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;

import gnu.regexp.RE;
import gnu.regexp.REException;
import gnu.regexp.REMatch;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.text.Collator;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* Class to hold random utility functions
*/
public final class Util {
  private static final InstantConverter TIME_CONVERTER_FROM_CALENDAR = ConverterManager.getInstance().getInstantConverter(new GregorianCalendar());
  private static final InstantConverter TIME_CONVERTER_FROM_JODA = ConverterManager.getInstance().getInstantConverter(new DateTime());
  private static final Chronology CHRON = new DateTime().getChronology();
  private static final DateTimeFormatter FORMATTER = ISODateTimeFormat.basicDateTime();
  private static final SimpleDateFormat SIMPLE_DATE_FORMATTER1 =
      new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
  private static final SimpleDateFormat SIMPLE_DATE_FORMATTER2 =
      new SimpleDateFormat("yyyy-MM-dd HH:mm:ss'Z'");

  private static final Logger LOGGER = Logger.getLogger(Util.class.getName());

  /**
   * Formats last modified date (yyyy-MM-dd HH:mm:ss'Z') to Calendar format
   *
   * @param strDate
   * @throws ParseException
   */
  public static Calendar siteDataStringToCalendar(final String strDate)
      throws ParseException {
    final Date dt = SIMPLE_DATE_FORMATTER2.parse(strDate);
    final Calendar c = Calendar.getInstance();
    c.setTime(dt);
    return c;
  }

  /**
   * Returns calendar as a formatted String (yyyy-MM-dd HH:mm:ss'Z')
   *
   * @param date The calendar input to be converted to a date time string
   * @return The formatted date time string
   */
  public static String calendarToSiteDataString(final Calendar cal){
    return SIMPLE_DATE_FORMATTER2.format(new Date(cal.getTimeInMillis()));
  }
 
  /**
   * Converts a DateTime format to Calendar
   *
   * @param date
   */
  public static Calendar jodaToCalendar(final DateTime date) {
    final long millis = TIME_CONVERTER_FROM_JODA.getInstantMillis(date, CHRON);
    final GregorianCalendar cal = new GregorianCalendar();
    cal.setTimeInMillis(millis);
    return cal;
  }

  /**
   * Converts a Calendar format to DateTime
   *
   * @param cal
   */
  public static DateTime calendarToJoda(final Calendar cal) {
    final long millis = TIME_CONVERTER_FROM_CALENDAR.getInstantMillis(cal, CHRON);
    DateTime dt = new DateTime(millis, CHRON);
    return dt;
  }

  /**
   * Return a String formated DateTime value
   *
   * @param date
   */
  public static String formatDate(final DateTime date) {
    String dtString = FORMATTER.print(date);
    return dtString;
  }

  /**
   * Return a string formated Calendar value
   *
   * @param cal
   */
  public static String formatDate(final Calendar cal) {
    String dtString = FORMATTER.print(calendarToJoda(cal));
    return dtString;
  }

  /**
   * Gets the current date and time in a readable format for logging.
   *
   * @return The formatted date time string
   */
  public static String getCurrentTimestampString() {
    return SIMPLE_DATE_FORMATTER1.format(new Date());
  }

  /**
   * returns a DateTime value for a well-formed string
   *
   * @param str
   */
  public static DateTime parseDate(final String str) {
    DateTime dt = FORMATTER.parseDateTime(str);
    return dt;
  }

  /**
   * return collator for default locale
   */
  public static Collator getCollator() {
    final Collator collator = Collator.getInstance();
    collator.setStrength(Collator.PRIMARY);
    return collator;
  }

  /**
   * return collator for a given locale
   *
   * @param locale
   */
  public static Collator getCollator(final Locale locale) {
    if (locale == null) {
      return getCollator();
    }
    final Collator collator = Collator.getInstance(locale);
    collator.setStrength(Collator.PRIMARY);
    return collator;
  }

  /**
   * Desc : match the String Value with the string array.
   *
   * @param strList
   * @param strValue
   */
  public static boolean match(final String[] strList, final String strValue,
      final StringBuffer matchedPattern) {
    if ((strList == null) || (strValue == null)) {
      return false;
    }
    for (final String strURLPat : strList) {
      if ((strURLPat != null) && (strURLPat.length() > 0)) {
        String strDecodedValue = strValue;
        String strDecodedURLPat = strURLPat;
        try {
          strDecodedValue = URLDecoder.decode(strValue, "UTF-8");
          strDecodedURLPat = URLDecoder.decode(strURLPat, "UTF-8");
        } catch (final Exception e) {
          LOGGER.log(Level.FINE, e.getMessage());
          strDecodedValue = strValue;
          strDecodedURLPat = strURLPat;
        }
        if (matcher(strDecodedURLPat, strDecodedValue)) {
          if (matchedPattern != null) {
            matchedPattern.append(strURLPat);
          }
          return true;
        }
      }
    }
    return false;
  }

  /**
   * Matches a url with a pattern. Mimics GSA's pattern matching
   *
   * @param pattern
   * @param strValue
   */
  private static boolean matcher(final String pattern, final String strValue) {
    // null check for the arguments
    if ((pattern == null) | (strValue == null)) {
      return false;
    }

    // If the pattern starts with "#" then its a comment so ignore
    if (pattern.startsWith(SPConstants.HASH)) {
      return false;
    }

    // if the pattern starts with "-", remove the "-" from begin and proceed
    if (pattern.startsWith(SPConstants.MINUS)) {
      return false;
    }

    // handle "contains:"
    // if pattern starts with "contains:" then check if the URL contains the
    // string in pattern
    if (pattern.startsWith(SPConstants.CONTAINS)) {
      final StringBuffer tempBuffer = new StringBuffer(pattern);
      final String strContainKey = new String(
          tempBuffer.delete(0, SPConstants.CONTAINS.length()));
      RE re;
      try {
        re = new RE(strContainKey); // with case
        final REMatch reMatch = re.getMatch(strValue);
        if (reMatch != null) {
          return true;
        }
        return false;
      } catch (final REException e) {
        LOGGER.log(Level.FINE, e.getMessage());
        return false;
      }
    }

    // handle regexp
    // if pattern starts with "regexp:", then check for regex match with
    // case
    if (pattern.startsWith(SPConstants.REGEXP)) {
      final StringBuffer tempBuffer = new StringBuffer(pattern);
      final String strRegexPattrn = new String(
          tempBuffer.delete(0, SPConstants.REGEXP.length()));
      RE re;
      try {
        re = new RE(strRegexPattrn);
        final REMatch reMatch = re.getMatch(strValue);
        if (reMatch != null) {
          return true;
        }
        return false;
      } catch (final REException e) {
        LOGGER.log(Level.FINE, e.getMessage());
        return false;
      }
    }

    // handle regexpCase
    // if pattern starts with "regexpCase:", then check for regex match with
    // case
    if (pattern.startsWith(SPConstants.REGEXP_CASE)) {
      final StringBuffer tempBuffer = new StringBuffer(pattern);
      final String strRegexCasePattrn = new String(
          tempBuffer.delete(0, SPConstants.REGEXP_CASE.length()));
      RE re;
      try {
        re = new RE(strRegexCasePattrn);
        final REMatch reMatch = re.getMatch(strValue);
        if (reMatch != null) {
          return true;
        }
        return false;
      } catch (final REException e) {
        LOGGER.log(Level.FINE, e.getMessage());
        return false;
      }
    }

    // handle regexpIgnoreCase
    // if pattern starts with "regexpIgnoreCase:", then check for regex
    // match without case
    if (pattern.startsWith(SPConstants.REGEXP_IGNORE_CASE)) {
      final StringBuffer tempBuffer = new StringBuffer(pattern);
      final String strRegexIgnoreCasePattrn = new String(
          tempBuffer.delete(0, SPConstants.REGEXP_IGNORE_CASE.length()));
      RE re;
      try {
        re = new RE(strRegexIgnoreCasePattrn, RE.REG_ICASE); // ignore
        // case
        final REMatch reMatch = re.getMatch(strValue);
        if (reMatch != null) {
          return true;
        }
        return false;
      } catch (final REException e) {
        LOGGER.log(Level.FINE, e.getMessage());
        return false;
      }
    }

    // handle "^" and "$"
    if (pattern.startsWith(SPConstants.CARET)
        || pattern.endsWith(SPConstants.DOLLAR)) {
      StringBuffer tempBuffer = new StringBuffer(pattern);
      boolean bDollar = false;
      String strValueModified = strValue;
      if (pattern.startsWith(SPConstants.CARET)) {
        URL urlValue;
        try {
          urlValue = new URL(strValue);
          int port = urlValue.getPort();
          if (port == -1) {
            port = urlValue.getDefaultPort();
            strValueModified = urlValue.getProtocol() + SPConstants.URL_SEP
                + urlValue.getHost() + SPConstants.COLON + port
                + urlValue.getFile();
          }
        } catch (final MalformedURLException e1) {
          LOGGER.log(Level.FINE, e1.getMessage());
          return false;
        }
        tempBuffer = new StringBuffer(pattern);
        final int indexOfStar = tempBuffer.indexOf("*");
        if (indexOfStar != -1) {
          tempBuffer.replace(indexOfStar, indexOfStar + "*".length(), "[0-9].*");
        } else {
          tempBuffer.delete(0, "^".length());
          if (pattern.endsWith(SPConstants.DOLLAR)) {
            bDollar = true;
            tempBuffer.delete(tempBuffer.length() - SPConstants.DOLLAR.length(), tempBuffer.length());
          }
          try {
            final URL urlPatt = new URL(tempBuffer.toString());
            final int port = urlPatt.getPort();

            final String strHost = urlPatt.getHost().toString();

            if ((port == -1) && (strHost != null) && (strHost.length() != 0)) {
              tempBuffer = new StringBuffer("^" + urlPatt.getProtocol()
                  + SPConstants.URL_SEP + urlPatt.getHost() + ":[0-9].*"
                  + urlPatt.getPath());
            }
            if (bDollar) {
              tempBuffer.append(SPConstants.DOLLAR);
            }
          } catch (final MalformedURLException e) {
            LOGGER.log(Level.FINE, e.getMessage());
            tempBuffer = new StringBuffer(pattern);
          }
        }
      }

      RE re;
      try {
        re = new RE(tempBuffer);
        final REMatch reMatch = re.getMatch(strValueModified);
        if (reMatch != null) {
          return true;
        }
        return false;
      } catch (final REException e) {
        LOGGER.log(Level.FINE, e.getMessage());
        return false;
      }
    }

    // url decode the pattern
    String patternDecoded = pattern;
    try {
      patternDecoded = URLDecoder.decode(pattern, "UTF-8");
    } catch (final Exception e) {
      LOGGER.log(Level.FINE, e.getMessage());
      patternDecoded = pattern;
    }

    if (patternDecoded == null) {
      return false;
    }

    boolean containProtocol = false;
    try {
      final RE re = new RE(SPConstants.URL_SEP);
      final REMatch reMatch = re.getMatch(patternDecoded);
      if (reMatch != null) {
        containProtocol = true; // protocol is present
      }
    } catch (final REException e) {
      containProtocol = false;
    }

    if (containProtocol) {
      // split the test URL into two parts
      String urlValue1stPart = null;
      String urlValue2ndPart = null;

      URL urlValue;
      try {
        urlValue = new URL(strValue);
        int port = urlValue.getPort();
        if (port == -1) {
          port = urlValue.getDefaultPort();
        }
        urlValue1stPart = urlValue.getProtocol() + SPConstants.URL_SEP
            + urlValue.getHost() + SPConstants.COLON + port;
        urlValue2ndPart = urlValue.getFile();

        if (urlValue2ndPart != null) {
          if (!urlValue2ndPart.startsWith(SPConstants.SLASH)) {
            urlValue2ndPart = SPConstants.SLASH + urlValue2ndPart;
          }
        }
      } catch (final MalformedURLException e1) {
        LOGGER.log(Level.FINE, e1.getMessage());
        return false;
      }

      // split the pattern into two parts
      String urlPatt1stPart = null;
      String urlPatt2ndPart = null;
      boolean bPortStar = false;
      try {
        final URL urlPatt = new URL(patternDecoded);
        final int port = urlPatt.getPort();
        String strPort = "";
        if (port == -1) {
          strPort = "[0-9].*";
        } else {
          strPort = port + "";
        }
        urlPatt1stPart = "^" + urlPatt.getProtocol() + SPConstants.URL_SEP
            + urlPatt.getHost() + SPConstants.COLON + strPort;
        if (!(urlPatt.getFile()).startsWith(SPConstants.SLASH)) { // The
          // pattern
          // must
          // have
          // "/"
          // at
          // after
          // the
          // port
          return false;
        }
        urlPatt2ndPart = "^" + urlPatt.getFile();
      } catch (final MalformedURLException e) {
        LOGGER.log(Level.FINE, e.getMessage());
        bPortStar = true;
      }

      if (bPortStar) {
        final int indexOfStar = patternDecoded.indexOf("*");
        if (indexOfStar != -1) {
          urlPatt1stPart = "^" + patternDecoded.substring(0, indexOfStar)
              + "[0-9].*";
          if (!(patternDecoded.substring(indexOfStar + 1)).startsWith(SPConstants.SLASH)) {
            return false;
          }
          urlPatt2ndPart = "^" + patternDecoded.substring(indexOfStar + 1);
        }
      }

      // check 1st part of both with ignorecase
      RE re;
      try {
        re = new RE(urlPatt1stPart, RE.REG_ICASE); // ignore case for
        // 1st part
        REMatch reMatch = re.getMatch(urlValue1stPart);
        if (reMatch != null) {
          // check 2nd part of both with case
          re = new RE(urlPatt2ndPart);
          reMatch = re.getMatch(urlValue2ndPart);
          if (reMatch != null) {
            return true;
          }
        }
      } catch (final REException e) {
        LOGGER.log(Level.FINE, e.getMessage());
        return false;
      } catch (final Exception e) {
        LOGGER.log(Level.FINE, e.getMessage());
        return false;
      }
    } else {
      String pat1 = null;
      String pat2 = null;
      // split the pattern into two parts
      if (patternDecoded.indexOf(SPConstants.SLASH) != -1) {
        if (patternDecoded.indexOf(SPConstants.COLON) == -1) {
          pat1 = patternDecoded.substring(0, patternDecoded.indexOf(SPConstants.SLASH))
              + ":[0-9].*";
        } else {
          pat1 = patternDecoded.substring(0, patternDecoded.indexOf(SPConstants.SLASH));
        }
        pat2 = patternDecoded.substring(patternDecoded.indexOf(SPConstants.SLASH));
      } else {
        // The pattern must have "/" at after the port
        return false;
      }

      pat1 = "^.*://.*" + pat1;
      pat2 = "^" + pat2;
      URL urlValue;
      try {
        urlValue = new URL(strValue);
        int port = urlValue.getPort();
        if (port == -1) {
          port = urlValue.getDefaultPort();
        }
        final String urlValue1stPart = urlValue.getProtocol()
            + SPConstants.URL_SEP + urlValue.getHost() + SPConstants.COLON
            + port;
        String urlValue2ndPart = urlValue.getFile();

        if (urlValue2ndPart != null) {
          if (!urlValue2ndPart.startsWith(SPConstants.SLASH)) {
            urlValue2ndPart = SPConstants.SLASH + urlValue2ndPart;
          }
        }

        RE re;
        try {
          re = new RE(pat1, RE.REG_ICASE); // ignore case for 1st part
          REMatch reMatch = re.getMatch(urlValue1stPart);
          if (reMatch != null) {
            re = new RE(pat2); // with case for 2nd part
            reMatch = re.getMatch(urlValue2ndPart);
            if (reMatch != null) {
              return true;
            }
          }
        } catch (final REException e) {
          LOGGER.log(Level.FINE, e.getMessage());
          return false;
        }
      } catch (final MalformedURLException e) {
        LOGGER.log(Level.FINE, e.getMessage());
        return false;
      }
    }

    return false;
  }

  /**
   * return username in the format domain\\username or groupname in the format
   * domain\\groupname.
   *
   * @param name user or group name
   * @param domain
   */
  public static String getUserNameWithDomain(final String name,
      final String domain) {
    String tmpName = name;
    if (name == null) {
      LOGGER.log(Level.FINEST, "returning [ " + name + " for input [ "
          + tmpName + " ], domain [ " + domain + " ]. ");
      return null;
    }
    String modified_name = null;
    if (name.lastIndexOf(SPConstants.AT) != -1) {
      final String[] user_or_group_and_domain = name.split(SPConstants.AT);
      // user@domain or group@domain
      if ((user_or_group_and_domain != null)
          && (user_or_group_and_domain.length == 2)) {
        modified_name = user_or_group_and_domain[1]
            + SPConstants.BACKSLASH + user_or_group_and_domain[0];
        // convert to domain\\user format
        LOGGER.log(Level.FINEST, "returning [ " + modified_name
            + " for input [ " + tmpName + " ], domain [ " + domain + " ]. ");
        return modified_name;
      }
    } else if (name.lastIndexOf(SPConstants.SLASH) != -1) {
      final String[] user_and_domain = name.split(SPConstants.SLASH);// domain/user
      if ((user_and_domain != null) && (user_and_domain.length == 2)) {
        modified_name = user_and_domain[0] + SPConstants.BACKSLASH
            + user_and_domain[1];
        // convert to domain\\user format
        LOGGER.log(Level.FINEST, "returning [ " + modified_name
            + " for input [ " + tmpName + " ], domain [ " + domain + " ]. ");
        return modified_name;
      }
    } else if (name.lastIndexOf(SPConstants.BACKSLASH) != -1) {
      LOGGER.log(Level.FINEST, "returning [ " + name + " for input [ "
          + tmpName + " ], domain [ " + domain + " ]. ");
      return name;
    } else if (null != domain) {
      modified_name = domain + SPConstants.BACKSLASH + name;
      LOGGER.log(Level.FINEST, "returning [ " + modified_name + " for input [ "
          + tmpName + " ], domain [ " + domain + " ]. ");
      return modified_name;
    }
    LOGGER.log(Level.FINEST, "returning [ " + name + " for input [ " + tmpName
        + " ], domain [ " + domain + " ]. ");
    return name;
  }

  /**
   * return username in the format username@domain or groupname in the format
   * domain\\groupname.
   *
   * @param name user or group name
   * @param domain
   */
  public static String getUserNameAtDomain(String name, final String domain) {
    String tmpname = name;
    if (name == null) {
      LOGGER.log(Level.WARNING, "returning [ " + name + " for input [ "
          + tmpname + " ], domain [ " + domain + " ]. ");
      return null;
    }
    String modified_Name = null;
    if (name.lastIndexOf(SPConstants.BACKSLASH) != -1) {
      name = name.replace(SPConstants.BACKSLASH_CHAR, SPConstants.SLASH_CHAR);
      // else gives pattern exception while parsing
    }
    if (name.lastIndexOf(SPConstants.SLASH) != -1) {
      final String[] user_or_group_and_domain = name.split(SPConstants.SLASH);
      if ((user_or_group_and_domain != null)
          && (user_or_group_and_domain.length == 2)) {
        modified_Name = user_or_group_and_domain[1] + SPConstants.AT
            + user_or_group_and_domain[0];
        // convert to user@domain or group@domain format
        LOGGER.log(Level.FINEST, "returning [ " + modified_Name
            + " for input [ " + tmpname + " ], domain [ " + domain + " ]. ");
        return modified_Name;
      }
    } else if (name.lastIndexOf(SPConstants.AT) != -1) {
      LOGGER.log(Level.FINEST, "returning [ " + name + " for input [ "
          + tmpname + " ], domain [ " + domain + " ]. ");
      // when username/groupname is already in required format
      return name;
    } else if (null != domain) {
      modified_Name = name + SPConstants.AT + domain;
      LOGGER.log(Level.FINEST, "returning [ " + modified_Name + " for input [ "
          + tmpname + " ], domain [ " + domain + " ]. ");
      return modified_Name;
    }
    LOGGER.log(Level.FINEST, "returning [ " + name + " for input [ " + tmpname
        + " ], domain [ " + domain + " ]. ");
    return name;
  }

  /**
   * finds and return domain from a username
   *
   * @param userName
   */
  public static String getDomainFromUsername(String userName) {
    String domain = null;
    if (userName != null) {
      if (userName.indexOf(SPConstants.AT_CHAR) != -1) {
        final String[] cred = userName.split(SPConstants.AT);
        if ((cred != null) && (cred.length == 2)) {
          domain = cred[1];
        }
      } else if (userName.indexOf(SPConstants.BACKSLASH) != -1) {
        userName = userName.replace(SPConstants.BACKSLASH_CHAR,
            SPConstants.SLASH_CHAR);
        final String[] cred = userName.split(SPConstants.SLASH);
        if ((cred != null) && (cred.length == 2)) {
          domain = cred[0];
        }
      }
    }
    LOGGER.log(Level.FINEST, "domain found as " + domain + " for username [ "
        + userName + " ]. ");
    return domain;
  }

  /**
   * Parses a username to get the username without domain info
   *
   * @param userName
   */
  public static String getUserFromUsername(String userName) {
    String tmpUsername = userName;
    String user = userName;
    if (userName != null) {
      if (userName.indexOf(SPConstants.AT_CHAR) != -1) {
        final String[] cred = userName.split(SPConstants.AT);
        if ((cred != null) && (cred.length == 2)) {
          user = cred[0];
        }
      } else if (userName.indexOf(SPConstants.BACKSLASH) != -1) {
        userName = userName.replace(SPConstants.BACKSLASH_CHAR,
            SPConstants.SLASH_CHAR);
        final String[] cred = userName.split(SPConstants.SLASH);
        if ((cred != null) && (cred.length == 2)) {
          user = cred[1];
        }
      }
    }
    LOGGER.log(Level.FINEST, "input [ " + tmpUsername + " ], output [ " + user
        + " ]. ");
    return user;
  }

  /**
   * COnversion: domain\\username <=> username@domain
   *
   * @param userName
   */
  private static String switchUserNameFormat(final String userName) {
    if (userName.indexOf(SPConstants.AT) != -1) {
      return getUserNameWithDomain(userName, null);
    } else {
      return getUserNameAtDomain(userName, null);
    }
  }

  /**
   * Gets a {@code Principal} for the given SharePoint local group.
   *
   * @param namespace the GSA local namespace for the group
   * @param scope the site collection URL for the group
   * @param groupName the name for the group
   */
  public static Principal getSharePointGroupPrincipal(String namespace,
      String scope, String groupName) {
    return new Principal(UNQUALIFIED, namespace,
        "[" + scope + "]" + groupName, EVERYTHING_CASE_INSENSITIVE);
  }

  /**
   * Get the web application url from a SharePoint URL
   *
   * @param web
   */
  public static String getWebApp(final String web) {
    URL url;
    try {
      url = new URL(web);
    } catch (final MalformedURLException e) {
      LOGGER.log(Level.FINE, web + " ... " + e.getMessage());
      return null;
    }

    final int port = url.getPort() == -1 ? url.getDefaultPort() : url.getPort();
    final String res = url.getProtocol() + SPConstants.URL_SEP + url.getHost()
        + SPConstants.COLON + port;
    LOGGER.log(Level.FINEST, "input [ " + web + " ], output [ " + res + " ]. ");
    return res;
  }

  /**
   * Checks if a string is numeric
   *
   * @param value
   */
  public static boolean isNumeric(final String value) {
    try {
      Integer.parseInt(value);
      return true;
    } catch (final Exception e) {
      LOGGER.log(Level.FINE, value + " ... " + e.getMessage());
      return false;
    }
  }

  /**
   * Converts a string to a numeric.
   *
   * @param value The string to convert
   * @param defaultValue The default value to return in case of error
   */
  public static int parseNumeric(final String value, int defaultValue) {
    try {
      return Integer.parseInt(value);
    } catch (Exception e) {
      LOGGER.log(Level.FINE, "Unable to parse integral value " +
          value + ".", e);
      return defaultValue;
    }
  }

  /**
   * Checks to see if the incoming value is a valid URL
   *
   * @param value
   */
  public static boolean isURL(final String value) {
    try {
      final URL url = new URL(value);
    } catch (final Exception e) {
      LOGGER.log(Level.FINE, value + " ... " + e.getMessage());
      return false;
    }
    return true;
  }

  /**
   * Gets the original DOcID if the document ID has been modified in respect to
   * the Content feed mode.
   *
   * @param docId
   * @param feedType
   */
  public static String getOriginalDocId(final String docId, FeedType feedType) {
    String originalDocId = docId;
    if (docId == null) {
      return docId;
    }
    if (FeedType.CONTENT_FEED == feedType) {
      String[] parts = docId.split(SPConstants.BACKSLASH
          + SPConstants.DOC_TOKEN); // because | is a regexp character
      // and has to be delimited.
      if (parts.length == 2) {
        originalDocId = parts[1];
      }
    }
    LOGGER.log(Level.FINEST, "docId [ " + docId + " ], originalDocID [ "
        + originalDocId + " ]. ");
    return originalDocId;
  }

  /**
   * return URL without default port if contained the default port.
   *
   * @param strUrl
   */
  public static String getWebURLForWSCall(final String strUrl) {
    String tmpSPURL = strUrl;
    if (strUrl != null) {
      try {
        final URL url = new URL(strUrl);
        final String hostTmp = url.getHost();
        final String protocolTmp = url.getProtocol(); // to remove the
        // hard-coded
        // protocol
        int portTmp = -1;
        if (-1 != url.getPort()) {
          if (url.getPort() != url.getDefaultPort()) {
            portTmp = url.getPort();
          }
        }
        String siteNameTmp = url.getPath();
        String strSPURL = protocolTmp + SPConstants.URL_SEP + hostTmp;
        if (portTmp != -1) {
          strSPURL += SPConstants.COLON + portTmp;
        }
        if (siteNameTmp.endsWith(SPConstants.SLASH)) {
          siteNameTmp = siteNameTmp.substring(0, siteNameTmp.length() - 1);
        }
        strSPURL += siteNameTmp;
        return strSPURL;

      } catch (final MalformedURLException e) {
        LOGGER.log(Level.WARNING, e.toString());
      }
    }
    LOGGER.log(Level.FINEST, "input [ " + tmpSPURL + " ], output [ " + strUrl
        + " ]. ");
    return strUrl;
  }

  /**
   * Normalizes the attribute's name to make better sense to the end user.
   *
   * @param metaName the attribute name as returned by the web service the
   *          normalized attribute name
   */
  public static String normalizeMetadataName(String metaName) {
    String metaNameNormalized = metaName;
    if (null != metaNameNormalized) {
      if (metaNameNormalized.startsWith(SPConstants.OWS)) {
        metaNameNormalized = metaNameNormalized.replaceFirst(SPConstants.OWS, "");
      }
      if (metaNameNormalized.startsWith(SPConstants.METAINFO)) {
        metaNameNormalized = metaNameNormalized.replaceFirst(SPConstants.METAINFO, "");
      }
      if (metaNameNormalized.startsWith(SPConstants.VTI)) {
        metaNameNormalized = metaNameNormalized.replaceFirst(SPConstants.VTI, "");
      }
      metaNameNormalized = metaNameNormalized.replaceAll(SPConstants.ENCODED_SPACE, " ");
    }
    LOGGER.log(Level.FINEST, "metaName [ " + metaName
        + " ], metaNameNormalized [ " + metaNameNormalized + " ]. ");
    return metaNameNormalized;
  }

  /**
   * Normalizes the attribute's value to make better sense to the end user.
   *
   * @param metaValue the attribute value as returned by the web service
   * @return the normalized attribute value
   */
  public static String normalizeMetadataValue(String metaValue) {
    String metaValNormalized = metaValue;
    if (null != metaValNormalized) {
      final Matcher match =
          SPConstants.ATTRIBUTE_VALUE_PATTERN.matcher(metaValue);
      if (match.find()) {
        String arr[] =
            metaValNormalized.split(SPConstants.SP_MULTI_VALUE_DELIMITER);
        // SharePoint makes us of ;# characters for Lookup Fields as will as
        // for some of the internal meta fields.
        // SharePoint Uses <integer ID1>;#value1;#<integer ID2>;#value2 for
        // multi choice lookup fields values.
        if (arr.length <= 2) {
          // Replace first integer with empty string only in case of internal
          // meta fields or lookup fields with single value. lookup fields with
          // more than 1 values will be processed in SPDocument.
          metaValNormalized = match.replaceFirst("");
        }
      }
    }
    LOGGER.log(Level.FINEST, "metaValue [ " + metaValue
        + " ], metaValNormalized [ " + metaValNormalized + " ]. ");
    return metaValNormalized;
  }
 
  public static List<String> processMultiValueMetadata(String metaValue) {
    if (null == metaValue) {
      return null;
    }
    List<String> valueToPass = new ArrayList<String>();
   
    final Matcher match =
        SPConstants.ATTRIBUTE_VALUE_PATTERN.matcher(metaValue);
    if (match.find()) {
      // This is a lookup field. We need to take alternate values only. Ignore
      // integer part.
      // <integer ID1>;#value1;#<integer ID2>;#value2
      String[] arr = metaValue.split(SPConstants.SP_MULTI_VALUE_DELIMITER);
      for (int i = 1; i < arr.length; i =i + 2) {
        if (!Strings.isNullOrEmpty(arr[i])) {
          valueToPass.add(arr[i]);
        }
      }
    } else if (metaValue.startsWith(SPConstants.SP_MULTI_VALUE_DELIMITER)
        && metaValue.endsWith(SPConstants.SP_MULTI_VALUE_DELIMITER)) {
      // This is a multi choice field. Values will be in
      // ;#value1;#value2;# format.
      String[] arr = metaValue.split(SPConstants.SP_MULTI_VALUE_DELIMITER);
      for (String value : arr) {
        if (value.length() > 0) {
          valueToPass.add(value);
        }
      }
    } else {
      valueToPass.add(metaValue);
    }
    return valueToPass;   
  }

  /**
   * A file writter
   *
   * @param filePath absolute path of the file
   * @param info message to be written
   */
  public static void logInfo(final String filePath, final String info) {
    File file = new File(filePath);
    try {
      final FileWriter fw = new FileWriter(file, true);
      final PrintWriter pw = new PrintWriter(fw);

      final Calendar cal = Calendar.getInstance();
      final SimpleDateFormat formater = new SimpleDateFormat(
          "yyyy-MM-dd HH:mm:ss");

      pw.println(formater.format(cal.getTime()) + " : " + info);
      pw.flush();
      pw.close();
    } catch (final IOException e) {
      LOGGER.log(Level.WARNING, "failed to log info [ " + info
          + " ] at filePath [ " + filePath + " ]. ", e);
    } catch (final Throwable e) {
      LOGGER.log(Level.WARNING, "failed to log info [ " + info
          + " ] at filePath [ " + filePath + " ]. ", e);
    }
  }

  /**
   * URL encoder.
   *
   * @param strURL
   */
  public static String encodeURL(final String strURL) {
    try {
      URL url = new URL(strURL);
      // URI does the encoding of the URL automatically and also checks
      // for the valid URL
      final URI uri = new URI(url.getProtocol(), null, url.getHost(),
          url.getPort(), url.getPath(), url.getQuery(), url.getRef());
      return uri.toASCIIString();
    } catch (final Exception e) {
      LOGGER.log(Level.SEVERE, "Malformed URL [ " + strURL + " ]. ");
      return strURL;
    }
  }

  /**
   * @param strURL
   */
  public static String getHost(final String strURL) {
    URL url;
    try {
      url = new URL(strURL);
    } catch (final Exception e) {
      LOGGER.log(Level.SEVERE, "Malformed URL [ " + strURL + " ]. ");
      return null;
    }
    return url.getHost();
  }

  public static boolean isFQDN(String serverName) {
    if (serverName.indexOf(SPConstants.PERIOD) == -1
        || serverName.lastIndexOf(SPConstants.PERIOD) == serverName.length() - 1) {
      return false;
    } else {
      try {
        InetAddress.getByName(serverName);
      } catch (UnknownHostException e) {
        return false;
      }
    }
    return true;
  }

  /**
   * Re-writes a given URL using the alias mapping rule specified.
   *
   * @param url URL to be re-written/mapped
   * @param aliasMap the alias mapping rules
   * @param fqdn If true, resulting URLs are converted into fqdn format. If
   *          false, URLs are returned just by applying the alias mapping rules.
   *          No further attempt will be made to re-write them.
   */
  public static String doAliasMapping(final String url,
      Map<String, String> aliasMap, boolean fqdn) throws MalformedURLException {
    URL objURL = new URL(url);
    String strUrl = "";

    boolean matched = false;
    // processing of alias values
    if ((null != aliasMap) && (null != aliasMap.keySet())) {
      for (final Iterator<String> aliasItr = aliasMap.keySet().iterator(); aliasItr.hasNext();) {

        String aliasPattern = aliasItr.next();
        String aliasValue = aliasMap.get(aliasPattern);

        if ((aliasPattern == null) || (aliasValue == null)) {
          continue;
        }
        aliasPattern = aliasPattern.trim();
        aliasValue = aliasValue.trim();
        if (aliasPattern.equalsIgnoreCase("")
            || aliasValue.equalsIgnoreCase("")) {
          continue;
        }

        URL patternURL = null;
        String aliasPatternURL = aliasPattern;
        if (aliasPattern.startsWith(SPConstants.GLOBAL_ALIAS_IDENTIFIER)) {
          aliasPatternURL = aliasPattern.substring(1);
        }

        try {
          patternURL = new URL(aliasPatternURL);
        } catch (final MalformedURLException e) {
          LOGGER.log(Level.WARNING, "Malformed alias pattern: "
              + aliasPatternURL, e);
        }
        if (patternURL == null) {
          continue;
        }

        if (!objURL.getProtocol().equalsIgnoreCase(patternURL.getProtocol())) {
          continue;
        }

        if (!objURL.getHost().equalsIgnoreCase(patternURL.getHost())) {
          continue;
        }

        if (aliasPattern.startsWith(SPConstants.GLOBAL_ALIAS_IDENTIFIER)) {
          aliasPattern = aliasPattern.substring(1);
          if (patternURL.getPort() == -1) {
            aliasPattern = patternURL.getProtocol() + SPConstants.URL_SEP
                + patternURL.getHost();
            if (objURL.getPort() != -1) {
              aliasPattern += SPConstants.COLON + objURL.getPort();
            }
            aliasPattern += patternURL.getFile();
          }
        } else if ((objURL.getPort() == -1)
            && (patternURL.getPort() == patternURL.getDefaultPort())) {
          aliasPattern = patternURL.getProtocol() + SPConstants.URL_SEP
              + patternURL.getHost() + patternURL.getFile();
        } else if ((objURL.getPort() == objURL.getDefaultPort())
            && (patternURL.getPort() == -1)) {
          aliasPattern = patternURL.getProtocol() + SPConstants.URL_SEP
              + patternURL.getHost() + SPConstants.COLON
              + patternURL.getDefaultPort() + patternURL.getFile();
        } else if (objURL.getPort() != patternURL.getPort()) {
          continue;
        }

        if (url.startsWith(aliasPattern)) {
          LOGGER.config("document url[" + url
              + "] has matched against alias source URL [ " + aliasPattern
              + " ]");
          strUrl = aliasValue;
          final String restURL = url.substring(aliasPattern.length());
          if (!strUrl.endsWith(SPConstants.SLASH)
              && !restURL.startsWith(SPConstants.SLASH)) {
            strUrl += SPConstants.SLASH;
          }
          strUrl += restURL;
          matched = true;
          LOGGER.config("document url[" + url + "] has been re-written to [ "
              + strUrl + " ] in respect to the aliasing.");
          break;
        }
      }
    }

    if (!matched) {
      strUrl = objURL.getProtocol() + SPConstants.URL_SEP;
      strUrl += getFQDNHostName(objURL.getHost(), fqdn) + SPConstants.COLON;
      final int portNo = objURL.getPort();
      if (portNo != -1) {
        strUrl += portNo;
      } else {
        strUrl += objURL.getDefaultPort();
      }
      strUrl += objURL.getFile();
    }

    return strUrl;
  }

  /**
   * Converts a host name to FQDN using Java's
   * {@link InetAddress#getCanonicalHostName()}
   *
   * @param hostName
   * @return the host name in FQDN format
   */
  private static String getFQDNHostName(final String hostName, boolean fqdn) {
    if (fqdn) {
      InetAddress ia = null;
      try {
        ia = InetAddress.getByName(hostName);
      } catch (final UnknownHostException e) {
        LOGGER.log(Level.WARNING, "Exception occurred while converting to FQDN, hostname [ "
            + hostName + " ].", e);
      }
      if (ia != null) {
        return ia.getCanonicalHostName();
      }
    }
    return hostName;
  }

  /**
   * Return group name with domain name i.e. domain\\groupname
   *
   * @param groupName the group/user name
   * @param domain the domain
   * @return a group/user name with domain
   */
  public static String getGroupNameWithDomain(final String groupName,
      final String domain) {
    return getUserNameWithDomain(groupName, domain);
  }

  /**
   * Return group name at domain name i.e. groupname@domain
   *
   * @param groupName the group/user name
   * @param domain the domain
   * @return a group/user name with domain
   */
  public static String getGroupNameAtDomain(String groupName,
      final String domain) {
    return getUserNameAtDomain(groupName, domain);
  }

  /**
   * Finds the connector name from the provided connector instance
   * directory path by tokenizing the path and getting the leaf
   * directory name.
   *
   * @param googleConnectorWorkDir the connector instance directory
   * @return the connector instance name
   */
  public static String getConnectorNameFromDirectoryUrl(
      String googleConnectorWorkDir) {
    String directory = null;
    StringTokenizer tokenizer = new StringTokenizer(googleConnectorWorkDir,
        File.separator);
    while (tokenizer.hasMoreTokens()) {
      directory = tokenizer.nextToken();
    }
    return directory;
  }

  /**
   * An interface used for making SOAP requests.
   */
  public interface RequestExecutor<T> {
    /**
     * Called to make a SOAP request.
     *
     * @param ws the web service interface to use to make the request
     * @return the request result
     */
    T onRequest(final BaseWS ws) throws Throwable;

    /**
     * Called when an exception occurs when make the web service request.
     *
     * @param e the exception that was thrown
     */
    void onError(final Throwable e);
  }

  /**
   * Makes a web service request.
   *
   * @param ctx the context
   * @param ws the web service interface to use to make the request
   * @param executor the interface that makes the request and handles errors
   * @return the request result
   */
  public static <T> T makeWSRequest(SharepointClientContext ctx, BaseWS ws,
      RequestExecutor<T> executor) {
    try {
      return executor.onRequest(ws);
    } catch (AxisFault af) {
      // Handling of username formats for different authentication models.
      // Switch the username format from domain\\username to username@domain
      // or vice versa.
      if ((SPConstants.UNAUTHORIZED.indexOf(af.getFaultString()) != -1)
          && (ctx.getDomain() != null)) {
        final String username = switchUserNameFormat(ws.getUsername());
        LOGGER.info("Web service call failed for username [ "
            + ws.getUsername() + " ], re-trying with username [ "
            + username + " ].");
        ws.setUsername(username);
        try {
          return executor.onRequest(ws);
        } catch (final Throwable e) {
          executor.onError(e);
        }
      } else {
        executor.onError(af);
      }
    } catch (final Throwable e) {
      executor.onError(e);
    }
    return null;
  }

  /**
   * An interface used for making SOAP requests.
   */
  public interface RequestExecutorVoid {
    /**
     * Called to make a SOAP request.
     *
     * @param ws the web service interface to use to make the request
     */
    void onRequest(final BaseWS ws) throws Throwable;

    /**
     * Called when an exception occurs when make the web service request.
     *
     * @param e the exception that was thrown
     */
    void onError(final Throwable e);
  }

  /**
   * Makes a web service request.
   *
   * @param ctx the context
   * @param ws the web service interface to use to make the request
   * @param executor the interface that makes the request and handles errors
   */
  public static void makeWSRequestVoid(SharepointClientContext ctx, BaseWS ws,
      RequestExecutorVoid executor) {
    try {
      executor.onRequest(ws);
    } catch (AxisFault af) {
      // Handling of username formats for different authentication models.
      // Switch the username format from domain\\username to username@domain
      // or vice versa.
      if ((SPConstants.UNAUTHORIZED.indexOf(af.getFaultString()) != -1)
          && (ctx.getDomain() != null)) {
        final String username = switchUserNameFormat(ws.getUsername());
        LOGGER.info("Web service call failed for username [ "
            + ws.getUsername() + " ], re-trying with username [ "
            + username + " ].");
        ws.setUsername(username);
        try {
          executor.onRequest(ws);
        } catch (final Throwable e) {
          executor.onError(e);
        }
      } else {
        executor.onError(af);
      }
    } catch (final Throwable e) {
      executor.onError(e);
    }
  }
}
TOP

Related Classes of com.google.enterprise.connector.sharepoint.client.Util

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.