package edu.stanford.nlp.sempre.freebase.utils;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import edu.stanford.nlp.io.IOUtils;
import fig.basic.LogInfo;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
/**
* Utils for handling freebase data dump files
*
* @author jonathanberant
*/
public final class FreebaseUtils {
private FreebaseUtils() { }
public static final Pattern DELIMITER_PATTERN = Pattern.compile("\t");
public static final String NAME_PROPERTY = "/type/object/name";
public static final String ALIAS_PROPERTY = "/common/topic/alias";
public static final String TYPE_PROPERTY = "/type/object/type";
public static final String PROFESSION_PROPERTY = "/people/person/profession";
public static final String MID_PREFIX = "/m/";
public static final String COMMON_DOMAIN_PREFIX = "/common/";
public static final String USER_DOMAIN_PREFIX = "/user/";
public static final String BASE_DOMAIN_PREFIX = "/base/";
public static final String FREEBASE_DOMAIN_PREFIX = "/freebase/";
public static final String DATA_DOMAIN_PREFIX = "/dataworld/";
public static final String TYPE_DOMAIN_PREFIX = "/type/";
// indices in data dump file
public static final int MID_INDEX = 0;
public static final int PROPERTY_INDEX = 1;
public static final int LANGUAGE_INDEX = 2;
public static final int VALUE_INDEX = 2;
public static final int DATE_INDEX = 3;
public static final int NAME_INDEX = 3;
/** Checks if a string is a valid MID */
public static boolean isMid(String str) {
return str.startsWith("/m/");
}
public static boolean isValidPropertyLine(String line) {
String[] tokens = DELIMITER_PATTERN.split(line);
return tokens.length == 3 &&
isMid(tokens[MID_INDEX]) &&
isMid(tokens[VALUE_INDEX]) &&
!isMid(tokens[PROPERTY_INDEX]) &&
isValidTypePrefix(tokens[PROPERTY_INDEX]);
}
public static boolean isValidPropertyLineWithDate(String line) {
String[] tokens = DELIMITER_PATTERN.split(line);
boolean regularProperty = tokens.length == 3 &&
isMid(tokens[MID_INDEX]) &&
!isMid(tokens[PROPERTY_INDEX]) &&
isValidTypePrefix(tokens[PROPERTY_INDEX]);
boolean dateProperty =
tokens.length == 4 &&
isMid(tokens[MID_INDEX]) &&
isValidTypePrefix(tokens[PROPERTY_INDEX]) &&
tokens[2].equals("") &&
isDate(tokens[3]);
return regularProperty || dateProperty;
}
public static boolean isDate(String dateCandidate) {
boolean res = true;
if (dateCandidate.startsWith("-")) {
dateCandidate = dateCandidate.substring(1);
}
int i = 0;
for (; i < Math.min(4, dateCandidate.length()); ++i) {
if (!Character.isDigit(dateCandidate.charAt(i))) {
res = false;
break;
}
}
if (i != 4)
res = false;
if (dateCandidate.length() > 4 && dateCandidate.charAt(4) != '-')
res = false;
return res;
}
public static String extractDate(String dateCandidate) {
boolean neg = false;
if (dateCandidate.startsWith("-")) {
neg = true;
dateCandidate = dateCandidate.substring(1);
}
return neg ? "-" + dateCandidate.substring(0, 4) : dateCandidate.substring(0, 4);
}
public static boolean isValidTypePrefix(String type) {
if (type.equals("/type/datetime"))
return true;
return !(type.startsWith(BASE_DOMAIN_PREFIX) || type.startsWith(MID_PREFIX) || type.startsWith(COMMON_DOMAIN_PREFIX) ||
type.startsWith(USER_DOMAIN_PREFIX) ||
type.startsWith(DATA_DOMAIN_PREFIX) ||
type.startsWith(FREEBASE_DOMAIN_PREFIX) ||
type.startsWith(TYPE_DOMAIN_PREFIX) ||
type.startsWith("/guid/"));
}
public static String getNoPrefixMid(String line) {
return DELIMITER_PATTERN.split(line)[MID_INDEX].substring(MID_PREFIX.length());
}
public static String getProperty(String line) {
return DELIMITER_PATTERN.split(line)[PROPERTY_INDEX];
}
public static String getValue(String line) {
return DELIMITER_PATTERN.split(line)[VALUE_INDEX];
}
public static String getDateValue(String line) {
return DELIMITER_PATTERN.split(line)[DATE_INDEX];
}
public static String getName(String line) {
return DELIMITER_PATTERN.split(line)[NAME_INDEX];
}
public static boolean isArg1Equal2Mid(String mid, String tupleTokens) {
return DELIMITER_PATTERN.split(tupleTokens)[MID_INDEX].equals(mid);
}
public static Map<String, String> loadMid2NameMap(String filename) throws IOException {
LogInfo.log("Loading mid to name file...");
Map<String, String> res = new HashMap<String, String>();
BufferedReader reader = IOUtils.getBufferedFileReader(filename);
String line;
while ((line = reader.readLine()) != null) {
String[] tokens = line.split("\t");
res.put(tokens[0], tokens[1]);
}
LogInfo.log("Loaded " + res.keySet().size() + " MIDs");
return res;
}
public static BiMap<Short, String> loadProperties(String propertyFileName) throws IOException {
BiMap<Short, String> res = HashBiMap.create();
BufferedReader reader = IOUtils.getBufferedFileReader(propertyFileName);
String line;
short id = 1;
while ((line = reader.readLine()) != null) {
res.put(id++, line);
}
return res;
}
public static boolean isUnary(String property) {
property = FormatConverter.fromDotToSlash(property);
return (property.equals(TYPE_PROPERTY) || property.equals(PROFESSION_PROPERTY));
}
public static boolean isNameProperty(String property) {
property = FormatConverter.fromDotToSlash(property);
return (property.equals(ALIAS_PROPERTY) || property.equals(NAME_PROPERTY));
}
}