use of org.collectionspace.chain.csp.schema.FieldSet in project application by collectionspace.
the class GenericStorage method simpleRetrieveJSON.
/**
* return data just as the service layer gives it to the App layer
* no extra columns required
* @param creds
* @param cache
* @param filePath
* @param servicesurl
* @param thisr
* @return
* @throws ExistException
* @throws UnimplementedException
* @throws UnderlyingStorageException
*/
public JSONObject simpleRetrieveJSON(CSPRequestCredentials creds, CSPRequestCache cache, String filePath, String servicesurl, Record thisr) throws ExistException, UnimplementedException, UnderlyingStorageException {
String csid = "";
if (filePath == null) {
filePath = "";
}
String[] path_parts = filePath.split("/");
if (path_parts.length > 1)
csid = path_parts[1];
else
csid = filePath;
JSONObject out = new JSONObject();
try {
String softpath = filePath;
if (thisr.hasSoftDeleteMethod()) {
softpath = softpath(filePath);
}
if (thisr.hasHierarchyUsed("screen")) {
softpath = hierarchicalpath(softpath);
}
if (thisr.isMultipart()) {
ReturnedMultipartDocument doc = conn.getMultipartXMLDocument(RequestMethod.GET, servicesurl + softpath, null, creds, cache);
if ((doc.getStatus() < 200 || doc.getStatus() >= 300))
throw new UnderlyingStorageException("Does not exist ", doc.getStatus(), softpath);
for (String section : thisr.getServicesRecordPathKeys()) {
String path = thisr.getServicesRecordPath(section);
String[] parts = path.split(":", 2);
if (doc.getDocument(parts[0]) != null) {
convertToJson(out, doc.getDocument(parts[0]), thisr, "GET", section, csid);
}
}
// If this record has hierarchy, will pull out the relations section and map it to the hierarchy
// fields (special case handling of XML-JSON
handleHierarchyPayloadRetrieve(thisr, doc, out, csid);
} else {
ReturnedDocument doc = conn.getXMLDocument(RequestMethod.GET, servicesurl + softpath, null, creds, cache);
if ((doc.getStatus() < 200 || doc.getStatus() >= 300))
throw new UnderlyingStorageException("Does not exist ", doc.getStatus(), softpath);
convertToJson(out, doc.getDocument(), thisr, "GET", "common", csid);
}
} catch (ConnectionException e) {
throw new UnderlyingStorageException("Service layer exception" + e.getLocalizedMessage(), e.getStatus(), e.getUrl(), e);
} catch (JSONException e) {
throw new UnderlyingStorageException("Service layer exception", e);
}
/*
* Get data for any sub records that are part of this record e.g. contact in person, blob in media
*/
try {
for (FieldSet fs : thisr.getAllSubRecords("GET")) {
Boolean validator = true;
Record sr = fs.usesRecordId();
if (fs.usesRecordValidator() != null) {
validator = false;
if (out.has(fs.usesRecordValidator())) {
String test = out.getString(fs.usesRecordValidator());
if (test != null && !test.equals("")) {
validator = true;
}
}
}
if (validator) {
String getPath = servicesurl + filePath + "/" + sr.getServicesURL();
if (null != fs.getServicesUrl()) {
getPath = fs.getServicesUrl();
}
if (fs.getWithCSID() != null) {
getPath = getPath + "/" + out.getString(fs.getWithCSID());
}
// need to get update and delete working? tho not going to be used for media as handling blob seperately
if (fs instanceof Group) {
JSONObject outer = simpleRetrieveJSON(creds, cache, getPath, "", sr);
JSONArray group = new JSONArray();
group.put(outer);
out.put(fs.getID(), group);
}
if (fs instanceof Repeat) {
// NEED TO GET A LIST OF ALL THE THINGS
JSONArray repeat = new JSONArray();
String path = getPath;
while (!path.equals("")) {
JSONObject data = getListView(creds, cache, path, sr.getServicesListPath(), "csid", false, r);
if (data.has("listItems")) {
String[] results = (String[]) data.get("listItems");
for (String result : results) {
JSONObject rout = simpleRetrieveJSON(creds, cache, getPath + "/" + result, "", sr);
// add in csid so I can do update with a modicum of confidence
rout.put("_subrecordcsid", result);
repeat.put(rout);
}
}
if (data.has("pagination")) {
Integer ps = Integer.valueOf(data.getJSONObject("pagination").getString("pageSize"));
Integer pn = Integer.valueOf(data.getJSONObject("pagination").getString("pageNum"));
Integer ti = Integer.valueOf(data.getJSONObject("pagination").getString("totalItems"));
if (ti > (ps * (pn + 1))) {
JSONObject restrictions = new JSONObject();
restrictions.put("pageSize", Integer.toString(ps));
restrictions.put("pageNum", Integer.toString(pn + 1));
path = getRestrictedPath(getPath, restrictions, sr.getServicesSearchKeyword(), "", false, "");
// need more values
} else {
path = "";
}
}
}
// group.put(outer);
out.put(fs.getID(), repeat);
}
}
}
} catch (Exception e) {
// ignore exceptions for sub records at the moment - make it more intelligent later
// throw new UnderlyingStorageException("Service layer exception",e);
}
return out;
}
use of org.collectionspace.chain.csp.schema.FieldSet in project application by collectionspace.
the class GenericStorage method autocreateJSON.
/**
* Convert the JSON from the UI Layer into XML for the Service layer while using the XML structure from cspace-config.xml
* Send the XML through to the Service Layer to store it in the database
* The Service Layer returns a url to the object we just stored.
* @param {ContextualisedStorage} root
* @param {CSPRequestCredentials} creds
* @param {CSPRequestCache} cache
* @param {String} filePath part of the path to the Service URL (containing the type of object)
* @param {JSONObject} jsonObject The JSON string coming in from the UI Layer, containing the object to be stored
* @return {String} csid The id of the object in the database
*/
@Override
public String autocreateJSON(ContextualisedStorage root, CSPRequestCredentials creds, CSPRequestCache cache, String filePath, JSONObject jsonObject, JSONObject restrictions) throws ExistException, UnimplementedException, UnderlyingStorageException {
try {
ReturnedURL url = null;
Document doc = null;
// used by userroles and permroles as they have complex urls
if (r.hasPrimaryField()) {
for (String section : r.getServicesRecordPathKeys()) {
doc = XmlJsonConversion.convertToXml(r, jsonObject, section, "POST");
String path = r.getServicesURL();
path = path.replace("*", getSubCsid(jsonObject, r.getPrimaryField()));
String restrictedPath = getRestrictedPath(path, restrictions, null);
deleteJSON(root, creds, cache, restrictedPath);
url = conn.getURL(RequestMethod.POST, restrictedPath, doc, creds, cache);
}
} else {
String restrictedPath = getRestrictedPath(r.getServicesURL(), restrictions, null);
// REM - We need a way to send query params (restrictions) on POST and UPDATE
url = autoCreateSub(creds, cache, jsonObject, doc, restrictedPath, r);
}
// I am developing this.. it might not work...
for (FieldSet fs : r.getAllSubRecords("POST")) {
Record sr = fs.usesRecordId();
// sr.getID()
if (sr.isType("authority")) {
// need to use code from configuredVocabStorage
} else {
String savePath = url.getURL() + "/" + sr.getServicesURL();
if (fs instanceof Field) {
// get the fields form inline XXX untested - might not work...
JSONObject subdata = new JSONObject();
// loop thr jsonObject and find the fields I need
for (FieldSet subfs : sr.getAllFieldTopLevel("POST")) {
String key = subfs.getID();
if (jsonObject.has(key)) {
subdata.put(key, jsonObject.get(key));
}
}
subautocreateJSON(root, creds, cache, sr, subdata, savePath);
} else if (fs instanceof Group) {
// JSONObject
if (jsonObject.has(fs.getID())) {
Object subdata = jsonObject.get(fs.getID());
if (subdata instanceof JSONObject) {
JSONObject subrecord = (JSONObject) subdata;
subautocreateJSON(root, creds, cache, sr, subrecord, savePath);
}
}
} else {
// JSONArray
if (jsonObject.has(fs.getID())) {
Object subdata = jsonObject.get(fs.getID());
if (subdata instanceof JSONArray) {
JSONArray subarray = (JSONArray) subdata;
for (int i = 0; i < subarray.length(); i++) {
JSONObject subrecord = subarray.getJSONObject(i);
subautocreateJSON(root, creds, cache, sr, subrecord, savePath);
}
}
}
}
}
}
return url.getURLTail();
} catch (ConnectionException e) {
String msg = e.getMessage();
if (e.getStatus() == 403) {
// permissions error
msg += " permissions error";
}
throw new UnderlyingStorageException(msg, e.getStatus(), e.getUrl(), e);
} catch (UnderlyingStorageException e) {
// REM - CSPACE-5632: Need to catch and rethrow this exception type to prevent throwing an "UnimplementedException" exception below.
throw e;
} catch (Exception e) {
throw new UnimplementedException("JSONException", e);
}
}
use of org.collectionspace.chain.csp.schema.FieldSet in project application by collectionspace.
the class GenericStorage method initializeGlean.
/**
* initialise the info for the glean array
*
* view_good keys are prefixed by the values found in the mini tag in the config file
* to help simplify deciding what to find and reduce irrelevant fan out,
* @param r
* @param view_good map of servicenames of fields to descriptors
* @param view_map map of csid to service name of field
* @param xxx_view_deurn
* @param view_search_optional
* @param view_merge map of fields needed if one field to the UI is really multiple fields in the services
* @param view_useCsid
*/
// CSPACE-5988: Allow maps to be passed as parameters, instead of using instance variables.
protected void initializeGlean(Record r, Map<String, String> view_good, Map<String, String> view_map, Set<String> xxx_view_deurn, Set<String> view_search_optional, Map<String, List<String>> view_merge, Map<String, List<String>> view_useCsid) {
// Number
if (r.getMiniNumber() != null) {
view_good.put("number", r.getMiniNumber().getID());
view_map.put(r.getMiniNumber().getServicesTag(), r.getMiniNumber().getID());
if (r.getMiniNumber().hasMergeData()) {
view_merge.put("number", r.getMiniNumber().getAllMerge());
}
if (r.getMiniNumber().hasAutocompleteInstance() || // values that do not start with urn:
r.isType("searchall"))
xxx_view_deurn.add(r.getMiniNumber().getID());
}
// Summary
if (r.getMiniSummary() != null) {
view_good.put("summary", r.getMiniSummary().getID());
view_map.put(r.getMiniSummary().getServicesTag(), r.getMiniSummary().getID());
if (r.getMiniSummary().hasMergeData()) {
view_merge.put("summary", r.getMiniSummary().getAllMerge());
}
if (r.getMiniSummary().hasAutocompleteInstance() || // values that do not start with urn:
r.isType("searchall"))
xxx_view_deurn.add(r.getMiniSummary().getID());
}
// complex summary list
if (r.getAllMiniDataSets().length > 0) {
for (String setName : r.getAllMiniDataSets()) {
String prefix = setName;
if (r.getMiniDataSetByName(prefix).length > 0 && !prefix.equals("")) {
for (FieldSet fs : r.getMiniDataSetByName(prefix)) {
view_map.put(fs.getServicesTag(), fs.getID());
view_good.put(prefix + "_" + fs.getID(), fs.getID());
if (fs instanceof Field) {
Field f = (Field) fs;
String fsID = f.getID();
// If the field is actually based upon another, marked use-csid,
// then put the name of that field in the view map instead.
// We need to glean that from the list results, so we can build
// the field from it.
String use_csid = f.useCsid();
if (use_csid != null && f.useCsidField() != null) {
String useID = f.useCsidField();
List<String> useStrings = new ArrayList<String>();
useStrings.add(useID);
useStrings.add(use_csid);
view_useCsid.put(prefix + "_" + fsID, useStrings);
// Need to ensure that we glean the useId value as well
view_good.put(prefix + "_" + useID, useID);
// Strictly speaking we should get the services tag for
// the field, but we'll cheat for simplicity, since it is
// almost always the ID, and we'll just insist that for
// useCsid that it must be. Sigh.
view_map.put(useID, useID);
}
// Single field
if (f.hasMergeData()) {
view_merge.put(prefix + "_" + fsID, f.getAllMerge());
for (String fm : f.getAllMerge()) {
if (fm != null) {
if (r.getFieldFullList(fm).hasAutocompleteInstance()) {
xxx_view_deurn.add(fsID);
}
}
}
}
if (f.hasAutocompleteInstance()) {
xxx_view_deurn.add(fsID);
}
}
}
}
}
}
// Special cases not currently supported in config. This is a hack, and once we figure out
// what a pattern looks like, we can consider configuring this somehow.
// The current support is for a return field that may or may not be present in list
// results. When it is, we want to pass it along to the UI
view_search_optional.add("related");
view_good.put("search_related", "related");
view_map.put("related", "related");
}
use of org.collectionspace.chain.csp.schema.FieldSet in project application by collectionspace.
the class GenericStorage method getPathsJSON.
/**
* Gets a list of csids of a certain type of record together with the pagination info
*/
@Override
public JSONObject getPathsJSON(ContextualisedStorage root, CSPRequestCredentials creds, CSPRequestCache cache, String rootPath, JSONObject restrictions) throws ExistException, UnimplementedException, UnderlyingStorageException {
try {
FieldSet dispNameFS = r.getDisplayNameField();
String displayNameFieldID;
boolean supportsTermCompletion;
if (dispNameFS != null) {
displayNameFieldID = dispNameFS.getID();
supportsTermCompletion = true;
} else {
displayNameFieldID = "";
supportsTermCompletion = false;
}
String path = getRestrictedPath(r.getServicesURL(), restrictions, r.getServicesSearchKeyword(), "", supportsTermCompletion, displayNameFieldID);
JSONObject data = getListView(creds, cache, path, r.getServicesListPath(), "csid", false, r);
return data;
} catch (ConnectionException e) {
throw new UnderlyingStorageException("Service layer exception" + e.getLocalizedMessage(), e.getStatus(), e.getUrl(), e);
} catch (UnsupportedEncodingException e) {
throw new UnderlyingStorageException("Service layer exception", e);
} catch (JSONException e) {
throw new UnderlyingStorageException("Service layer exception", e);
}
}
use of org.collectionspace.chain.csp.schema.FieldSet in project application by collectionspace.
the class GenericStorage method subautocreateJSON.
/**
* needs some tests.. just copied from ConfiguredVocabStorage
* @param root
* @param creds
* @param cache
* @param myr
* @param jsonObject
* @param savePrefix
* @return
* @throws ExistException
* @throws UnimplementedException
* @throws UnderlyingStorageException
*/
public String subautocreateJSON(ContextualisedStorage root, CSPRequestCredentials creds, CSPRequestCache cache, Record myr, JSONObject jsonObject, String savePrefix) throws ExistException, UnimplementedException, UnderlyingStorageException {
try {
ReturnedURL url = null;
Document doc = null;
// XXX I would hope this might be removed if userroles etc ever get improved to be more like the rest
if (myr.hasPrimaryField()) {
for (String section : myr.getServicesRecordPathKeys()) {
doc = XmlJsonConversion.convertToXml(myr, jsonObject, section, "POST");
String path = myr.getServicesURL();
path = path.replace("*", getSubCsid(jsonObject, myr.getPrimaryField()));
deleteJSON(root, creds, cache, path);
url = conn.getURL(RequestMethod.POST, path, doc, creds, cache);
}
} else {
url = autoCreateSub(creds, cache, jsonObject, doc, savePrefix, myr);
}
// create related sub records?
for (FieldSet allfs : myr.getAllSubRecords("POST")) {
Record sr = allfs.usesRecordId();
if (sr.isType("authority")) {
} else {
String savePath = url.getURL() + "/" + sr.getServicesURL();
if (jsonObject.has(sr.getID())) {
Object subdata = jsonObject.get(sr.getID());
if (subdata instanceof JSONArray) {
JSONArray subarray = (JSONArray) subdata;
for (int i = 0; i < subarray.length(); i++) {
JSONObject subrecord = subarray.getJSONObject(i);
subautocreateJSON(root, creds, cache, sr, subrecord, savePath);
}
} else if (subdata instanceof JSONObject) {
JSONObject subrecord = (JSONObject) subdata;
subautocreateJSON(root, creds, cache, sr, subrecord, savePath);
}
}
}
}
return url.getURLTail();
} catch (ConnectionException e) {
throw new UnderlyingStorageException("Connection exception" + e.getLocalizedMessage(), e.getStatus(), e.getUrl(), e);
} catch (JSONException e) {
throw new UnderlyingStorageException("Cannot parse surrounding JSON" + e.getLocalizedMessage(), e);
}
}
Aggregations