package edu.harvard.iq.dataverse.privateurl;
import edu.harvard.iq.dataverse.Dataset;
import edu.harvard.iq.dataverse.DatasetVersion;
import edu.harvard.iq.dataverse.DvObject;
import edu.harvard.iq.dataverse.RoleAssignment;
import edu.harvard.iq.dataverse.authorization.Permission;
import edu.harvard.iq.dataverse.authorization.RoleAssignee;
import edu.harvard.iq.dataverse.authorization.users.PrivateUrlUser;
import edu.harvard.iq.dataverse.engine.command.exception.CommandException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
/**
* Static, testable methods with no runtime dependencies.
*/
public class PrivateUrlUtil {
private static final Logger logger = Logger.getLogger(PrivateUrlUtil.class.getCanonicalName());
/**
* Use of this method should be limited to
* RoleAssigneeServiceBean.getRoleAssignee. If you have the
* {@link RoleAssignment} in your hand, just instantiate a
* {@link PrivateUrlUser} using the definitionPoint.
*
* @param identifier For example, "#42". The identifier is expected to start
* with "#" (the namespace for a PrivateUrlUser and its corresponding
* RoleAssignment) and end with the dataset id.
*
* @return A valid PrivateUrlUser (which like any User or Group is a
* RoleAssignee) if a valid identifier is provided or null.
*/
public static RoleAssignee identifier2roleAssignee(String identifier) {
String[] parts = identifier.split(PrivateUrlUser.PREFIX);
long datasetId;
try {
datasetId = new Long(parts[1]);
} catch (ArrayIndexOutOfBoundsException | NumberFormatException ex) {
logger.fine("Could not find dataset id in '" + identifier + "': " + ex);
return null;
}
return new PrivateUrlUser(datasetId);
}
/**
* @todo If there is a use case for this outside the context of Private URL,
* move this method to somewhere more centralized.
*/
static Dataset getDatasetFromRoleAssignment(RoleAssignment roleAssignment) {
if (roleAssignment == null) {
return null;
}
DvObject dvObject = roleAssignment.getDefinitionPoint();
if (dvObject == null) {
return null;
}
if (dvObject instanceof Dataset) {
return (Dataset) roleAssignment.getDefinitionPoint();
} else {
return null;
}
}
/**
* @return DatasetVersion if a draft or null.
*
* @todo If there is a use case for this outside the context of Private URL,
* move this method to somewhere more centralized.
*/
static public DatasetVersion getDraftDatasetVersionFromRoleAssignment(RoleAssignment roleAssignment) {
if (roleAssignment == null) {
return null;
}
Dataset dataset = getDatasetFromRoleAssignment(roleAssignment);
if (dataset != null) {
DatasetVersion latestVersion = dataset.getLatestVersion();
if (latestVersion.isDraft()) {
return latestVersion;
}
}
logger.fine("Couldn't find draft, returning null");
return null;
}
static public PrivateUrlUser getPrivateUrlUserFromRoleAssignment(RoleAssignment roleAssignment) {
if (roleAssignment == null) {
return null;
}
Dataset dataset = getDatasetFromRoleAssignment(roleAssignment);
if (dataset != null) {
PrivateUrlUser privateUrlUser = new PrivateUrlUser(dataset.getId());
return privateUrlUser;
}
return null;
}
/**
* @return PrivateUrlRedirectData or null.
*
* @todo Show the Exception to the user?
*/
public static PrivateUrlRedirectData getPrivateUrlRedirectData(RoleAssignment roleAssignment) {
PrivateUrlUser privateUrlUser = PrivateUrlUtil.getPrivateUrlUserFromRoleAssignment(roleAssignment);
String draftDatasetPageToBeRedirectedTo = PrivateUrlUtil.getDraftDatasetPageToBeRedirectedTo(roleAssignment);
try {
return new PrivateUrlRedirectData(privateUrlUser, draftDatasetPageToBeRedirectedTo);
} catch (Exception ex) {
logger.info("Exception caught trying to instantiate PrivateUrlRedirectData: " + ex);
return null;
}
}
/**
* Returns a relative URL or "UNKNOWN."
*/
static String getDraftDatasetPageToBeRedirectedTo(RoleAssignment roleAssignment) {
DatasetVersion datasetVersion = getDraftDatasetVersionFromRoleAssignment(roleAssignment);
return getDraftUrl(datasetVersion);
}
/**
* Returns a relative URL or "UNKNOWN."
*/
static String getDraftUrl(DatasetVersion draft) {
if (draft != null) {
Dataset dataset = draft.getDataset();
if (dataset != null) {
String persistentId = dataset.getGlobalId();
/**
* @todo Investigate why dataset.getGlobalId() yields the String
* "null:null/null" when I expect null value. This smells like a
* bug.
*/
if (!"null:null/null".equals(persistentId)) {
String relativeUrl = "/dataset.xhtml?persistentId=" + persistentId + "&version=DRAFT";
return relativeUrl;
}
}
}
return "UNKNOWN";
}
static PrivateUrl getPrivateUrlFromRoleAssignment(RoleAssignment roleAssignment, String dataverseSiteUrl) {
if (dataverseSiteUrl == null) {
logger.info("dataverseSiteUrl was null. Can not instantiate a PrivateUrl object.");
return null;
}
Dataset dataset = PrivateUrlUtil.getDatasetFromRoleAssignment(roleAssignment);
if (dataset != null) {
PrivateUrl privateUrl = new PrivateUrl(roleAssignment, dataset, dataverseSiteUrl);
return privateUrl;
} else {
return null;
}
}
static PrivateUrlUser getPrivateUrlUserFromRoleAssignment(RoleAssignment roleAssignment, RoleAssignee roleAssignee) {
if (roleAssignment != null) {
if (roleAssignee instanceof PrivateUrlUser) {
return (PrivateUrlUser) roleAssignee;
}
}
return null;
}
/**
* @return A list of the CamelCase "names" of required permissions, not the
* human-readable equivalents.
*
* @todo Move this to somewhere more central.
*/
public static List<String> getRequiredPermissions(CommandException ex) {
List<String> stringsToReturn = new ArrayList<>();
Map<String, Set<Permission>> map = ex.getFailedCommand().getRequiredPermissions();
map.entrySet().stream().forEach((entry) -> {
entry.getValue().stream().forEach((permission) -> {
stringsToReturn.add(permission.name());
});
});
return stringsToReturn;
}
}