io.prismic.Api Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of java-kit Show documentation
Show all versions of java-kit Show documentation
The developer kit to access Prismic.io repositories using the Java language.
The newest version!
package io.prismic;
import com.fasterxml.jackson.databind.JsonNode;
import io.prismic.core.HttpClient;
import java.io.IOException;
import java.io.InputStream;
import java.net.Proxy;
import java.util.*;
import java.util.Map.Entry;
/**
* Embodies an API endpoint, from which it is possible to make queries.
*
* This object should be instantiated once per webpage on your project,
* at the very beginning of the webpage, and then used for every subsequent document query.
*/
public class Api {
/**
* @return the kit version as declared in the pom.xml
*/
public static String getVersion() {
String path = "/version.properties";
InputStream stream = Api.class.getResourceAsStream(path);
if (stream == null) {
return "UNKNOWN";
}
Properties props = new Properties();
try {
props.load(stream);
stream.close();
return (String) props.get("version");
} catch (IOException e) {
return "UNKNOWN";
}
}
public static class Error extends RuntimeException {
public enum Code {
MALFORMED_URL,
AUTHORIZATION_NEEDED,
INVALID_TOKEN,
TOO_MANY_REQUESTS,
UNEXPECTED
}
final private Code code;
public Error(Code code, String message) {
super(message);
this.code = code;
}
public Error(Code code, String message, Throwable throwable) {
super(message, throwable);
this.code = code;
}
public Error(Code code, Throwable throwable) {
super(throwable);
this.code = code;
}
public Code getCode() {
return code;
}
public String toString() {
return ("[" + code + "] " + getMessage());
}
}
// --
/**
* Entry point to get an {@link Api} object.
* Example: API api = API.get("https://lesbonneschoses.prismic.io/api", null, new Cache.BuiltInCache(999), new Logger.PrintlnLogger());
*
* @param endpoint the endpoint of your prismic.io content repository, typically https://yourrepoid.prismic.io/api
* @param accessToken Your Oauth access token if you wish to use one (to access future content releases, for instance)
* @param defaultReference The default reference to use with queries. Will default to master if null
* @param cache instance of a class that implements the {@link Cache} interface, and will handle the cache
* @param logger instance of a class that implements the {@link Logger} interface, and will handle the logging
* @param proxy an optional java.net.Proxy instance that defines the http proxy to be used
* @return the usable API object
*/
public static Api get(String endpoint, String accessToken, String defaultReference, final Cache cache, final Logger logger, final Proxy proxy) {
final String url = (accessToken == null ? endpoint : (endpoint + "?access_token=" + HttpClient.encodeURIComponent(accessToken)));
JsonNode json = cache.getOrSet(
url,
5000L,
() -> HttpClient.fetch(url, logger, null, proxy)
);
ApiData apiData = ApiData.parse(json);
return new Api(apiData, accessToken, defaultReference, cache, logger, proxy);
}
/**
* Entry point to get an {@link Api} object.
* Example: API api = API.get("https://lesbonneschoses.prismic.io/api", null, new Cache.BuiltInCache(999), new Logger.PrintlnLogger());
*
* @param endpoint the endpoint of your prismic.io content repository, typically https://yourrepoid.prismic.io/api
* @param accessToken Your Oauth access token if you wish to use one (to access future content releases, for instance)
* @param defaultReference The default reference to use with queries. Will default to master if null
* @param cache instance of a class that implements the {@link Cache} interface, and will handle the cache
* @param logger instance of a class that implements the {@link Logger} interface, and will handle the logging
* @return the usable API object
*/
public static Api get(String endpoint, String accessToken, String defaultReference, final Cache cache, final Logger logger) {
return get(endpoint, accessToken, defaultReference, cache, logger, null);
}
public static Api get(String endpoint, String accessToken, final Cache cache, final Logger logger) {
return get(endpoint, accessToken, null, cache, logger, null);
}
public static Api get(String url, Cache cache, Logger logger) {
return get(url, null, cache, logger);
}
/**
* Entry point to get an {@link Api} object.
* Example: API api = API.get("https://lesbonneschoses.prismic.io/api", null);
*
* @param url the endpoint of your prismic.io content repository, typically https://yourrepoid.prismic.io/api
* @param accessToken Your Oauth access token if you wish to use one (to access future content releases, for instance)
* @return the usable API object
*/
public static Api get(String url, String accessToken, String defaultReference) {
return get(url, accessToken, defaultReference, Cache.DefaultCache.getInstance(), new Logger.NoLogger(), null);
}
/**
* Entry point to get an {@link Api} object.
* Example: API api = API.get("https://lesbonneschoses.prismic.io/api", null);
*
* @param url the endpoint of your prismic.io content repository, typically https://yourrepoid.prismic.io/api
* @param accessToken Your Oauth access token if you wish to use one (to access future content releases, for instance)
* @return the usable API object
*/
public static Api get(String url, String accessToken) {
return get(url, accessToken, Cache.DefaultCache.getInstance(), new Logger.NoLogger());
}
/**
* Entry point to get an {@link Api} object.
* Example: API api = API.get("https://lesbonneschoses.prismic.io/api");
*
* @param url the endpoint of your prismic.io content repository, typically https://yourrepoid.prismic.io/api
* @return the usable API object
*/
public static Api get(String url) {
return get(url, null);
}
// --
final private ApiData apiData;
final private String accessToken;
final private String defaultReference;
final private Cache cache;
final private Logger logger;
final private Proxy proxy;
/**
* Constructor to build a proper {@link Api} object. This is not to build an {@link Api} object
* from an {@link Api} endpoint (the most usual case). In this case, you'll use the API.get
method.
*
* @param apiData the data retrieved from the API document, ready to be stored in memory
* @param accessToken Your Oauth access token if you wish to use one (to access future content releases, for instance)
* @param defaultReference The default reference to use with queries. Will default to master if null
* @param cache instance of a class that implements the {@link Cache} interface, and will handle the cache
* @param logger instance of a class that implements the {@link Logger} interface, and will handle the logging
*/
public Api(ApiData apiData, String accessToken, String defaultReference, Cache cache, Logger logger, Proxy proxy) {
this.apiData = apiData;
this.accessToken = accessToken;
this.defaultReference = defaultReference;
this.cache = cache;
this.logger = logger;
this.proxy = proxy;
}
@Deprecated
public Api(ApiData apiData, String accessToken, Cache cache, Logger logger, Proxy proxy) {
this.apiData = apiData;
this.accessToken = accessToken;
this.defaultReference = null;
this.cache = cache;
this.logger = logger;
this.proxy = proxy;
}
public Logger getLogger() {
return logger;
}
public String getAccessToken() {
return accessToken;
}
public Cache getCache() {
return cache;
}
public Proxy getProxy() {
return proxy;
}
/**
* From a properly built {@link Api} object, returns the ref IDs (points in a prismic.io repository's timeline,
* whether in the past, in the present, or in the future) to which the passed credentials give access.
*
* @return the list of ref IDs
*/
public List getRefs() {
return apiData.getRefs();
}
/**
* From a properly built {@link Api} object, returns the ref with the corresponding label
*
* @param label the ref label as defined in the Writing Room
* @return the Ref, or null if not found
*/
public Ref getRef(String label) {
for (Ref ref: apiData.getRefs()) {
if (ref.getLabel().equals(label)) return ref;
}
return null;
}
/**
* From a properly built {@link Api} object, returns the map associating the bookmark names to their document IDs.
*
* Therefore, to get a bookmarked document's ID, it will look like this: api.getBookmarks().get("home")
*
* @return the map <name, id>
*/
public Map getBookmarks() {
return apiData.getBookmarks();
}
/**
* From a properly built {@link Api} object, returns the map associating the type names to their readable text.
*
* Therefore, to get a type's readable text, it will look like this: api.getTypes().get("blog")
*
* @return the map <name, text>
*/
public Map getTypes() {
return apiData.getTypes();
}
/**
* From a properly built {@link Api} object, returns the list of available tags.
*
* Therefore, to get all available tags, it will look like this: api.getTags()
*
* @return the list of tags
*/
public List getTags() {
return apiData.getTags();
}
/**
* From a properly built {@link Api} object, returns the Map of available form names.
*
* @return the map <name, proper_name>
*/
public Map getFormNames() {
Map formNames = new HashMap<>();
if (apiData.getForms() != null)
for(Entry formEntry : apiData.getForms().entrySet())
formNames.put(formEntry.getKey(), formEntry.getValue().getName());
return formNames;
}
/**
* From a properly built {@link Api} object, return a Form object that will allow to perform queries.
* Currently, all the forms offered by prismic.io are SearchForms, but this will change.
*
* To use it: api.get("everything").query(.....)......
*
* @param form the name of the form to query on
* @return the form to use to perform the query
* @see Form.SearchForm
*/
public Form.SearchForm getForm(String form) {
return new Form.SearchForm(this, apiData.getForms().get(form));
}
/**
* Return the current experiments on the repository
* @return the Experiments object
*/
public Experiments getExperiments() {
return apiData.getExperiments();
}
/**
* From a properly built {@link Api} object, returns the ref ID (points in a prismic.io repository's timeline,
* whether in the past, in the present, or in the future) of the master ref (the one presently live).
*
* @return the ref object representing the master ref
*/
public Ref getMaster() {
for(Ref ref: getRefs()) {
if(ref.isMasterRef()) return ref;
}
throw new Api.Error(Api.Error.Code.UNEXPECTED, "No master?");
}
/**
* Start a query defaulting on the master reference (you can still override it)
*/
public Form.SearchForm query() {
String reference = this.defaultReference == null ? this.getMaster().getRef() : this.defaultReference;
return this.getForm("everything").ref(reference);
}
/**
* Start a query defaulting on the master reference (you can still override it)
*/
public Form.SearchForm query(String q) {
String reference = this.defaultReference == null ? this.getMaster().getRef() : this.defaultReference;
return this.getForm("everything").ref(reference).query(q);
}
/**
* Start a query defaulting on the master reference (you can still override it)
*/
public Form.SearchForm query(Predicate... predicates) {
String reference = this.defaultReference == null ? this.getMaster().getRef() : this.defaultReference;
return this.getForm("everything").ref(reference).query(predicates);
}
/**
* Retrieve multiple documents from their ids on the given ref in the given language
*/
public Form.SearchForm getByIDs(Iterable ids, String ref, String lang) {
lang = lang != null ? lang : "*";
return this.query(Predicates.in("document.id", ids)).ref(ref).lang(lang);
}
/**
* Retrieve multiple documents from their ids on the given ref
*/
public Form.SearchForm getByIDs(Iterable ids, String ref) {
return this.getByIDs(ids, ref, null);
}
/**
* Retrieve multiple documents from their ids
*/
public Form.SearchForm getByIDs(Iterable ids) {
return this.getByIDs(ids, null, null);
}
/**
* Return the first document matching the predicate on the given ref in the given language
*/
public Document queryFirst(Predicate p, String ref, String lang) {
if (ref == null) {
ref = this.defaultReference == null ? this.getMaster().getRef() : this.defaultReference;
}
List results = query(p).ref(ref).lang(lang).submit().getResults();
if (results.size() > 0) {
return results.get(0);
} else {
return null;
}
}
/**
* Return the first document matching the predicate on the given reference
*/
public Document queryFirst(Predicate p, String ref) {
return queryFirst(p, ref, null);
}
/**
* Return the first document matching the predicate on the master reference
*/
public Document queryFirst(Predicate p) {
return queryFirst(p, null);
}
/**
* Retrieve a document by its ID on the given reference in the given language
*
* @return the document, or null if it doesn't exist
*/
public Document getByID(String documentId, String ref, String lang) {
lang = lang != null ? lang : "*";
return queryFirst(Predicates.at("document.id", documentId), ref, lang);
}
/**
* Retrieve a document by its ID on the given reference
*
* @return the document, or null if it doesn't exist
*/
public Document getByID(String documentId, String ref) {
return this.getByID(documentId, ref, null);
}
/**
* Retrieve a document by its ID on the master reference
*
* @return the document, or null if it doesn't exist
*/
public Document getByID(String documentId) {
return this.getByID(documentId, null);
}
/**
* Retrieve a document by its UID on the given reference in the given language
*
* @return the document, or null if it doesn't exist
*/
public Document getByUID(String documentType, String documentUID, String ref, String lang) {
lang = lang != null ? lang : "*";
return queryFirst(Predicates.at("my." + documentType + ".uid", documentUID), ref, lang);
}
/**
* Retrieve a document by its UID on the given reference
*
* @return the document, or null if it doesn't exist
*/
public Document getByUID(String documentType, String documentUID, String ref) {
return this.getByUID(documentType, documentUID, ref, null);
}
/**
* Retrieve a document by its UID on the master reference
*
* @return the document, or null if it doesn't exist
*/
public Document getByUID(String documentType, String documentUID) {
return this.getByUID(documentType, documentUID, null);
}
public Document getBookmark(String bookmark, String ref) {
if (ref == null) {
ref = this.defaultReference == null ? this.getMaster().getRef() : this.defaultReference;
}
return this.getByID(this.apiData.bookmarks.get(bookmark), ref);
}
public Document getBookmark(String bookmark) {
return getBookmark(bookmark, null);
}
/**
* Return the URL to display a given preview
* @param token as received from Prismic server to identify the content to preview
* @param linkResolver the link resolver to build URL for your site
* @param defaultUrl the URL to default to return if the preview doesn't correspond to a document
* (usually the home page of your site)
* @return the URL you should redirect the user to preview the requested change
*/
public String previewSession(String token, LinkResolver linkResolver, String defaultUrl, Proxy proxy) {
JsonNode tokenJson = HttpClient.fetch(token, logger, cache, proxy);
JsonNode mainDocumentId = tokenJson.path("mainDocument");
if (!mainDocumentId.isTextual()) {
return defaultUrl;
}
Response resp = query(Predicates.at("document.id", mainDocumentId.asText())).ref(token).lang("*").submit();
if (resp.getResults().size() == 0) {
return defaultUrl;
}
return linkResolver.resolve(resp.getResults().get(0));
}
public String getOAuthInitiateEndpoint() {
return apiData.getOAuthInitiateEndpoint();
}
public String getOAuthTokenEndpoint() {
return apiData.getOAuthTokenEndpoint();
}
// --
public static class ApiData {
final private List refs;
final private Map bookmarks;
final private Map types;
final private List tags;
final private Map forms;
final private String oauthInitiateEndpoint;
final private String oauthTokenEndpoint;
final private Experiments experiments;
public ApiData(List refs,
Map bookmarks,
Map types,
List tags,
Map forms,
Experiments experiments,
String oauthInitiateEndpoint,
String oauthTokenEndpoint) {
this.refs = Collections.unmodifiableList(refs);
this.bookmarks = Collections.unmodifiableMap(bookmarks);
this.types = Collections.unmodifiableMap(types);
this.tags = Collections.unmodifiableList(tags);
this.forms = Collections.unmodifiableMap(forms);
this.experiments = experiments;
this.oauthInitiateEndpoint = oauthInitiateEndpoint;
this.oauthTokenEndpoint = oauthTokenEndpoint;
}
public List getRefs() {
return refs;
}
public Map getBookmarks() {
return bookmarks;
}
public Map getTypes() {
return types;
}
public List getTags() {
return tags;
}
public Map getForms() {
return forms;
}
public String getOAuthInitiateEndpoint() {
return oauthInitiateEndpoint;
}
public String getOAuthTokenEndpoint() {
return oauthTokenEndpoint;
}
public Experiments getExperiments() {
return experiments;
}
// --
static ApiData parse(JsonNode json) {
List refs = new ArrayList<>();
Iterator refsJson = json.withArray("refs").elements();
while(refsJson.hasNext()) {
refs.add(Ref.parse(refsJson.next()));
}
Map bookmarks = new HashMap<>();
Iterator bookmarksJson = json.with("bookmarks").fieldNames();
while(bookmarksJson.hasNext()) {
String bookmark = bookmarksJson.next();
bookmarks.put(bookmark, json.with("bookmarks").path(bookmark).asText());
}
Map types = new HashMap<>();
Iterator typesJson = json.with("types").fieldNames();
while(typesJson.hasNext()) {
String type = typesJson.next();
types.put(type, json.with("types").path(type).asText());
}
List tags = new ArrayList<>();
Iterator tagsJson = json.withArray("tags").elements();
while(tagsJson.hasNext()) {
tags.add(tagsJson.next().asText());
}
Map forms = new HashMap<>();
Iterator formsJson = json.with("forms").fieldNames();
while(formsJson.hasNext()) {
String form = formsJson.next();
forms.put(form, Form.parse(json.with("forms").path(form)));
}
String oauthInitiateEndpoint = json.path("oauth_initiate").asText();
String oauthTokenEndpoint = json.path("oauth_token").asText();
Experiments experiments = Experiments.parse(json.path("experiments"));
return new ApiData(refs, bookmarks, types, tags, forms, experiments, oauthInitiateEndpoint, oauthTokenEndpoint);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy