package eu.europeana.cloud.service.commons.urls;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* Parser for URL used in eCloud API.<br/>
* <br/><br/>
* Some of possible URL patterns are:<br/>
* <p/>
* http://www.example.com/data-providers/DATAPROVIDER/data-sets/
* http://www.example.com/data-providers/DATAPROVIDER/data-sets/DATASET/
* http://www.example.com/data-providers/DATAPROVIDER/data-sets/DATASET/assignments/
* http://www.example.com/records/CLOUDID/
* http://www.example.com/records/CLOUDID/representations/
* http://www.example.com/records/CLOUDID/representations/REPRESENTATIONNAME/
* http://www.example.com/records/CLOUDID/representations/REPRESENTATIONNAME/versions/
* http://www.example.com/records/CLOUDID/representations/REPRESENTATIONNAME/versions/VERSION/
* http://www.example.com/records/CLOUDID/representations/REPRESENTATIONNAME/versions/VERSION/copy/
* http://www.example.com/records/CLOUDID/representations/REPRESENTATIONNAME/versions/VERSION/permit/
* http://www.example.com/records/CLOUDID/representations/REPRESENTATIONNAME/versions/VERSION/persist/
* http://www.example.com/records/CLOUDID/representations/REPRESENTATIONNAME/versions/VERSION/users/username/permit/permission/
* http://www.example.com/records/CLOUDID/representations/REPRESENTATIONNAME/versions/VERSION/files/
* http://www.example.com/records/CLOUDID/representations/REPRESENTATIONNAME/versions/VERSION/files/FILENAME/
*/
public class UrlParser {
private static final char DIR_SEPARATOR = '/';
private static final List<UrlPart> CLOUD_ID_URL_PATTERN = Arrays.asList(UrlPart.CONTEXT, UrlPart.RECORDS);
private static final List<UrlPart> REPRESENTATIONS_URL_PATTERN = Arrays.asList(UrlPart.CONTEXT, UrlPart.RECORDS, UrlPart.REPRESENTATIONS);
private static final List<UrlPart> REPRESENTATION_VERSION_URL_PATTERN = Arrays.asList(UrlPart.CONTEXT, UrlPart.RECORDS, UrlPart.REPRESENTATIONS, UrlPart.VERSIONS);
private static final List<UrlPart> REPRESENTATION_VERSION_FILE_URL_PATTERN = Arrays.asList(UrlPart.CONTEXT, UrlPart.RECORDS, UrlPart.REPRESENTATIONS, UrlPart.VERSIONS, UrlPart.FILES);
private static final List<UrlPart> DATASET_URL_PATTERN = Arrays.asList(UrlPart.CONTEXT, UrlPart.DATA_PROVIDERS, UrlPart.DATA_SETS);
private String[] values;
private Map<UrlPart, String> parts = new LinkedHashMap<>();
private URL resourceUrl;
private String appLocation;
private UrlBuilder ecloudUrlBuilder;
public UrlParser(String url) throws MalformedURLException {
resourceUrl = new URL(url);
appLocation = resourceUrl.getProtocol() + "://" + resourceUrl.getHost();
if (resourceUrl.getPort() != -1) {
appLocation += ":" + resourceUrl.getPort();
}
String path = resourceUrl.getPath();
if (path.startsWith("/")) {
path = path.substring(1);
}
values = path.split("/");
for (int i = 0; i < values.length; i++) {
if (values[i].equalsIgnoreCase(UrlPart.RECORDS.getValue())) {
if (values.length > i + 1) {
parts.put(UrlPart.RECORDS, values[i + 1]);
i++;
} else {
parts.put(UrlPart.RECORDS, null);
}
} else if (values[i].equalsIgnoreCase(UrlPart.REPRESENTATIONS.getValue())) {
if (values.length > i + 1) {
parts.put(UrlPart.REPRESENTATIONS, values[i + 1]);
i++;
} else {
parts.put(UrlPart.REPRESENTATIONS, null);
}
} else if (values[i].equalsIgnoreCase(UrlPart.VERSIONS.getValue())) {
if (values.length > i + 1) {
parts.put(UrlPart.VERSIONS, values[i + 1]);
i++;
} else {
parts.put(UrlPart.VERSIONS, null);
}
} else if (values[i].equalsIgnoreCase(UrlPart.FILES.getValue())) {
if (values.length > i + 1) {
final StringBuilder filePath = new StringBuilder();
do {
filePath.append(DIR_SEPARATOR + values[i + 1]);
} while (++i < values.length - 1);
parts.put(UrlPart.FILES, filePath.toString());
} else {
parts.put(UrlPart.FILES, null);
}
} else if (values[i].equalsIgnoreCase(UrlPart.DATA_SETS.getValue())) {
if (values.length > i + 1) {
parts.put(UrlPart.DATA_SETS, values[i + 1]);
i++;
} else {
parts.put(UrlPart.DATA_SETS, null);
}
} else if (values[i].equalsIgnoreCase(UrlPart.DATA_PROVIDERS.getValue())) {
if (values.length > i + 1) {
parts.put(UrlPart.DATA_PROVIDERS, values[i + 1]);
i++;
} else {
parts.put(UrlPart.DATA_PROVIDERS, null);
}
} else {
if (i == 0) {
parts.put(UrlPart.CONTEXT, values[i]);
}
}
}
ecloudUrlBuilder = new UrlBuilder(parts);
}
/**
* Checks if given URL points to data-sets list<br/>
* <p/>
* E.g. http://www.example.com/data-providers/DATAPROVIDER/data-sets/
*
* @return
*/
public boolean isUrlToDatasetsList() {
return matches(parts, DATASET_URL_PATTERN) && containEmptyValue(UrlPart.DATA_SETS);
}
/**
* Checks if given URL points to data-set<br/>
* <p/>
* E.g. http://www.example.com/data-providers/DATAPROVIDER/data-sets/DATASET/
*
* @return
*/
public boolean isUrlToDataset() {
return matches(parts, DATASET_URL_PATTERN) && containNonEmptyValue(UrlPart.DATA_SETS);
}
/**
* Checks if given URL points to representations list <br/>
* E.g. http://www.example.com/records/CLOUDID/
*
* @return
*/
public boolean isUrlToCloudId() {
return matches(parts, CLOUD_ID_URL_PATTERN) && containNonEmptyValue(UrlPart.RECORDS);
}
/**
* Checks if given URL points to representations list <br/>
* E.g. http://www.example.com/records/CLOUDID/representations/
*
* @return
*/
public boolean isUrlToRepresentations() {
return matches(parts, REPRESENTATIONS_URL_PATTERN) && containEmptyValue(UrlPart.REPRESENTATIONS);
}
/**
* Checks if given URL points to representation <br/>
* E.g. http://www.example.com/records/CLOUDID/representations/REPRESENTATIONNAME/
*
* @return
*/
public boolean isUrlToRepresentation() {
return matches(parts, REPRESENTATIONS_URL_PATTERN) && containNonEmptyValue(UrlPart.REPRESENTATIONS);
}
/**
* Checks if given URL points to representation versions list <br/>
* E.g. http://www.example.com/records/CLOUDID/representations/REPRESENTATIONNAME/versions
*
* @return
*/
public boolean isUrlToRepresentationVersions() {
return matches(parts, REPRESENTATION_VERSION_URL_PATTERN) && containEmptyValue(UrlPart.VERSIONS);
}
/**
* Checks if given URL points to representation version<br/>
* E.g. http://www.example.com/records/CLOUDID/representations/REPRESENTATIONNAME/versions/VERSION
*
* @return
*/
public boolean isUrlToRepresentationVersion() {
return matches(parts, REPRESENTATION_VERSION_URL_PATTERN) && containNonEmptyValue(UrlPart.VERSIONS);
}
/**
* Checks if given URL points to files list.<br/>
* E.g. http://127.0.0.1:8080/mcs/records/FUWQ4WMUGIGEHVA3X7FY5PA3DR5Q4B2C4TWKNILLS6EM4SJNTVEQ/representations/TIFF/versions/86318b00-6377-11e5-a1c6-90e6ba2d09ef/files
*
* @return
*/
public boolean isUrlToRepresentationVersionFiles() {
return containEmptyValue(UrlPart.FILES);
}
/**
* Checks if given URL points to file.<br/>
* E.g. http://127.0.0.1:8080/mcs/records/FUWQ4WMUGIGEHVA3X7FY5PA3DR5Q4B2C4TWKNILLS6EM4SJNTVEQ/representations/TIFF/versions/86318b00-6377-11e5-a1c6-90e6ba2d09ef/files/sampleFileName.txt
*
* @return
*/
public boolean isUrlToRepresentationVersionFile() {
return matches(parts, REPRESENTATION_VERSION_FILE_URL_PATTERN) && containNonEmptyValue(UrlPart.FILES);
}
private boolean containEmptyValue(UrlPart urlPart) {
return parts.containsKey(urlPart) && (parts.get(urlPart) == null || parts.get(urlPart).isEmpty());
}
private boolean containNonEmptyValue(UrlPart urlPart) {
return parts.containsKey(urlPart) && parts.get(urlPart) != null && !parts.get(urlPart).isEmpty();
}
private boolean matches(Map<UrlPart, String> parts, List<UrlPart> pattern) {
int counter = 0;
if (parts.keySet().size() != pattern.size()) {
return false;
}
for (Map.Entry<UrlPart, String> entry : parts.entrySet()) {
UrlPart urlPart = entry.getKey();
UrlPart part = pattern.get(counter);
if (part != null && urlPart.equals(part)) {
counter++;
continue;
}
return false;
}
return true;
}
//////////////////////
//
//////////////////////
/**
* Returns one part of given URL. If requested part does not exist, null will be returned
*
* @param urlPart which one part should be returned.
* @return
*/
public String getPart(UrlPart urlPart) {
return parts.get(urlPart);
}
/**
* Returns URL to version based on provided URL. If it is not possible UrlBuilderException will be thrown
*
* @return
*/
public String getVersionUrl() throws UrlBuilderException {
UrlBuilder ecloudUrlBuilder = new UrlBuilder(parts);
String result = ecloudUrlBuilder
.clear()
.withCloudID()
.withRepresentation()
.withVersion()
.build();
return appLocation + result;
}
public String getVersionsUrl() throws UrlBuilderException {
UrlBuilder ecloudUrlBuilder = new UrlBuilder(parts);
String result = ecloudUrlBuilder
.clear()
.withCloudID()
.withRepresentation()
.withVersionWithoutValue()
.build();
return appLocation + result;
}
public String getDataSetsUrl() throws UrlBuilderException {
ecloudUrlBuilder = new UrlBuilder(parts);
String result = ecloudUrlBuilder
.clear()
.withDataProvider()
.withDataSetWithoutValue().build();
return appLocation + result;
}
}