use of org.collectionspace.chain.csp.schema.Record in project application by collectionspace.
the class ConfiguredVocabStorage method updateJSON.
public void updateJSON(ContextualisedStorage root, CSPRequestCredentials creds, CSPRequestCache cache, JSONObject jsonObject, JSONObject restrictions, Record thisr, String savePath) throws ExistException, UnimplementedException, UnderlyingStorageException {
try {
String csid = savePath.split("/")[3];
Map<String, Document> body = new HashMap<String, Document>();
for (String section : r.getServicesRecordPathKeys()) {
String path = r.getServicesRecordPath(section);
String[] record_path = path.split(":", 2);
String[] tag_path = record_path[1].split(",", 2);
Document temp = createEntry(section, tag_path[0], tag_path[1], jsonObject, null, null, thisr, false);
if (temp != null) {
body.put(record_path[0], temp);
// log.info(temp.asXML());
}
}
handleHierarchyPayloadSend(thisr, body, jsonObject, csid);
ReturnedMultipartDocument out = conn.getMultipartXMLDocument(RequestMethod.PUT, savePath, body, creds, cache);
if (out.isErrorStatus()) {
if (out.isTransactionFailedStatus()) {
throw new UnderlyingStorageException(VOCABULARY_UPDATE_FAILED_MESSAGE + ": " + out.TRANSACTION_FAILED_MESSAGE, out.getStatus(), savePath);
} else {
throw new UnderlyingStorageException(VOCABULARY_UPDATE_FAILED_MESSAGE, out.getStatus(), savePath);
}
}
// subrecord update
for (FieldSet fs : thisr.getAllSubRecords("PUT")) {
Record sr = fs.usesRecordId();
// get list of existing subrecords
JSONObject existingcsid = new JSONObject();
JSONObject updatecsid = new JSONObject();
JSONArray createcsid = new JSONArray();
String getPath = savePath + "/" + sr.getServicesURL();
Integer subcount = 0;
String firstfile = "";
while (!getPath.equals("")) {
JSONObject data = getListView(creds, cache, getPath, sr.getServicesListPath(), "csid", false, sr);
String[] filepaths = (String[]) data.get("listItems");
subcount += filepaths.length;
if (firstfile.equals("") && subcount != 0) {
firstfile = filepaths[0];
}
for (String uri : filepaths) {
String path = uri;
if (path != null && path.startsWith("/"))
path = path.substring(1);
existingcsid.put(path, "original");
}
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 pgRestrictions = new JSONObject();
pgRestrictions.put("pageSize", Integer.toString(ps));
pgRestrictions.put("pageNum", Integer.toString(pn + 1));
getPath = getRestrictedPath(getPath, pgRestrictions, sr.getServicesSearchKeyword(), "", false, "");
// need more values
} else {
getPath = "";
}
}
}
// how does that compare to what we need
if (sr.isType("authority")) {
if (fs instanceof Field) {
JSONObject subdata = new JSONObject();
// loop thr jsonObject and find the fields I need
for (FieldSet subfs : sr.getAllFieldTopLevel("PUT")) {
String key = subfs.getID();
if (jsonObject.has(key)) {
subdata.put(key, jsonObject.get(key));
}
}
if (subcount == 0) {
// create
createcsid.put(subdata);
} else {
// update - there should only be one
String firstcsid = firstfile;
updatecsid.put(firstcsid, subdata);
existingcsid.remove(firstcsid);
}
} else if (fs instanceof Group) {
// subrecorddata.put(value);
if (jsonObject.has(fs.getID())) {
Object subdata = jsonObject.get(fs.getID());
if (subdata instanceof JSONObject) {
if (((JSONObject) subdata).has("_subrecordcsid")) {
String thiscsid = ((JSONObject) subdata).getString("_subrecordcsid");
// update
if (existingcsid.has(thiscsid)) {
updatecsid.put(thiscsid, (JSONObject) subdata);
existingcsid.remove(thiscsid);
} else {
// something has gone wrong... best just create it from scratch
createcsid.put(subdata);
}
} else {
// create
createcsid.put(subdata);
}
}
}
} else {
// need to find if we have csid's for each one
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);
if (subrecord.has("_subrecordcsid")) {
String thiscsid = subrecord.getString("_subrecordcsid");
// update
if (existingcsid.has(thiscsid)) {
updatecsid.put(thiscsid, (JSONObject) subdata);
existingcsid.remove(thiscsid);
} else {
// something has gone wrong... best just create it from scratch
createcsid.put(subdata);
}
} else {
// create
createcsid.put(subdata);
}
}
}
}
}
String savePathSr = savePath + "/" + sr.getServicesURL() + "/";
// do delete JSONObject existingcsid = new JSONObject();
Iterator<String> rit = existingcsid.keys();
while (rit.hasNext()) {
String key = rit.next();
deleteJSON(root, creds, cache, key, savePathSr, sr);
}
// do update JSONObject updatecsid = new JSONObject();
Iterator<String> keys = updatecsid.keys();
while (keys.hasNext()) {
String key = keys.next();
JSONObject value = updatecsid.getJSONObject(key);
String thissave = savePathSr + key;
updateJSON(root, creds, cache, value, new JSONObject(), sr, thissave);
// updateJSON( root, creds, cache, key, value, sr, savePathSr);
}
// do create JSONArray createcsid = new JSONArray();
for (int i = 0; i < createcsid.length(); i++) {
JSONObject value = createcsid.getJSONObject(i);
subautocreateJSON(root, creds, cache, sr, value, savePathSr);
}
}
}
// XXX dont currently update the shortID???
// cache.setCached(getClass(),new String[]{"shortId",vocab,filePath.split("/")[1]},shortId);
} 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);
} catch (UnsupportedEncodingException e) {
throw new UnimplementedException("UnsupportedEncodingException" + e.getLocalizedMessage(), e);
}
}
use of org.collectionspace.chain.csp.schema.Record in project application by collectionspace.
the class ServicesBaseClass method makeServicesStorage.
protected Storage makeServicesStorage() throws CSPDependencyException {
CSPManager cspm = getServiceManager();
ConfigRoot root = cspm.getConfigRoot();
Spec spec = (Spec) root.getRoot(Spec.SPEC_ROOT);
assertNotNull(spec);
// XXX this is spec specific testing that will break when we rename the object in the UI
Record r_obj = spec.getRecord("collection-object");
assertNotNull(r_obj);
assertEquals("collection-object", r_obj.getID());
assertEquals("cataloging", r_obj.getWebURL());
StorageGenerator gen = cspm.getStorage("service");
CSPRequestCredentials creds = gen.createCredentials();
creds.setCredential(ServicesStorageGenerator.CRED_USERID, spec.getAdminData().getAuthUser());
creds.setCredential(ServicesStorageGenerator.CRED_PASSWORD, spec.getAdminData().getAuthPass());
return gen.getStorage(creds, new RequestCache());
}
use of org.collectionspace.chain.csp.schema.Record in project application by collectionspace.
the class TestService method testJSONXML.
/**
* Tests conversion of a JSON file to XML. This implementation does not compare the
* resultant generated XML to an expected XML file. Instead, it converts the resultant
* XML back into JSON, and compares that round-trip JSON to an expected JSON file.
*
* @param spec
* @param objtype
* @param xmlfile Name of the file containing the expected XML (not currently used)
* @param jsonfile Name of the file containing JSON to be converted to XML
* @param returnedjsonfile Name of the file containing the expected round-trip JSON, converted back from XML
* @throws Exception
*/
private void testJSONXML(Spec spec, String objtype, String xmlfile, String jsonfile, String returnedjsonfile) throws Exception {
log.info("Converting JSON to XML for record type " + objtype);
Record r = spec.getRecord(objtype);
JSONObject j = getJSON(jsonfile);
// log.info("Original JSON:\n" + j.toString());
Map<String, Document> parts = new HashMap<String, Document>();
Document doc = null;
JSONObject testjson = new JSONObject();
for (String section : r.getServicesRecordPathKeys()) {
if (section.equals("common")) {
String path = r.getServicesRecordPath(section);
String[] record_path = path.split(":", 2);
doc = XmlJsonConversion.convertToXml(r, j, section, "");
parts.put(record_path[0], doc);
// log.info("After JSON->XML conversion:\n" + doc.asXML());
JSONObject repeatjson = org.collectionspace.chain.csp.persistence.services.XmlJsonConversion.convertToJson(r, doc, "", "common", "", // this is where we
"");
// we are considering
for (String name : JSONObject.getNames(repeatjson)) {
testjson.put(name, repeatjson.get(name));
}
// log.info("After XML->JSON re-conversion:\n" + testjson.toString());
}
}
// convert json -> xml and back to json and see if it still looks the
// same..
JSONObject expectedjson = getJSON(returnedjsonfile);
boolean result = JSONUtils.checkJSONEquivOrEmptyStringKey(expectedjson, testjson);
if (!result) {
log.info("Original JSON:\n" + j.toString());
log.info("After JSON->XML conversion:\n" + doc.asXML());
log.info("After XML->JSON re-conversion:\n" + testjson.toString());
}
assertTrue("JSON->XML->JSON round-trip for record type: " + objtype + " doesn't match original JSON", result);
}
use of org.collectionspace.chain.csp.schema.Record in project application by collectionspace.
the class ServiceBindingsGeneration method doServiceBindingsCommon.
/**
* if this.defaultonly - true then return
* service-bindings-common.xml - a shared prototype of core and common
* services, common to all tenants. This file has the basic definitions of
* the services, and the system, core, and common parts of each service. It
* includes the most common definitions of the field types, to make it easy
* to define a new tenant.
*
* else
* return domain specific file
*
* @return
*/
private String doServiceBindingsCommon(String serviceBindingVersion) {
Document doc = DocumentFactory.getInstance().createDocument();
Element root = doc.addElement(new QName("TenantBindingConfig", this.nstenant));
root.addAttribute("xsi:schemaLocation", this.schemaloc);
root.add(this.nsxsi);
// <tenant:tenantBinding version="0.1">
Element ele = root.addElement(new QName("tenantBinding", nstenant));
if (!this.defaultonly) {
ele.addAttribute("id", this.tenantSpec.getTenantId());
ele.addAttribute("name", this.tenantSpec.getTenant());
ele.addAttribute("displayName", this.tenantSpec.getTenantDisplay());
ele.addAttribute("createDisabled", Boolean.toString(this.tenantSpec.getCreateDisabled()));
}
ele.addAttribute("version", this.tenantSpec.getTenantVersion());
// <tenant:repositoryDomain name="default-domain" repositoryClient="nuxeo-java"/>
Element rele = ele.addElement(new QName("repositoryDomain", nstenant));
rele.addAttribute("name", this.tenantSpec.getRepositoryDomain());
rele.addAttribute("storageName", this.tenantSpec.getStorageName());
if (Tools.notEmpty(this.tenantSpec.getRepositoryName())) {
rele.addAttribute("repositoryName", this.tenantSpec.getRepositoryName());
}
rele.addAttribute("repositoryClient", this.tenantSpec.getRepositoryClient());
// Set remote clients
makeRemoteClients(ele);
// Set the bindings for email notifications
makeEmailBindings(ele);
// add in <tenant:properties> if required
makeProperties(ele);
// loop over each record type and add a <tenant:serviceBindings> element
for (Record r : this.spec.getAllRecords()) {
String tenantName = this.tenantSpec.getTenant();
String tenantId = this.tenantSpec.getTenantId();
String recordName = r.getRecordName();
if (log.isDebugEnabled()) {
log.debug(String.format("Config Generation: '%s' - Processing potential service bindings for record type '%s'", getConfigFile().getName(), recordName));
}
if (shouldGenerateServiceBinding(r) == true) {
Element serviceBindingsElement = null;
if (r.isType(RECORD_TYPE_RECORD) == true) {
// Records can be of several types -i.e., can be both a "record" type and a "vocabulary" type
String rtype = getServiceBindingType(r);
// e.g., <tenant:serviceBindings name="CollectionObjects" type="object" version="0.1">
serviceBindingsElement = ele.addElement(new QName("serviceBindings", nstenant));
serviceBindingsElement.addAttribute("id", r.getServicesTenantPl());
serviceBindingsElement.addAttribute("name", r.getServicesTenantPl());
serviceBindingsElement.addAttribute("type", rtype);
serviceBindingsElement.addAttribute("version", serviceBindingVersion);
if (r.isType(RECORD_TYPE_VOCABULARY) == true) {
// Vocabularies need unique short IDs
serviceBindingsElement.addAttribute(Record.REQUIRES_UNIQUE_SHORTID, Boolean.TRUE.toString());
// they also need to support replication
serviceBindingsElement.addAttribute(Record.SUPPORTS_REPLICATING, Boolean.toString(r.supportsReplicating()));
String remoteClientConfigName = r.getRemoteClientConfigName();
if (remoteClientConfigName != null && remoteClientConfigName.isEmpty() == false) {
serviceBindingsElement.addAttribute(Record.REMOTECLIENT_CONFIG_NAME, remoteClientConfigName);
}
}
addServiceBinding(r, serviceBindingsElement, nsservices, false, serviceBindingVersion);
} else if (r.isType(RECORD_TYPE_AUTHORITY)) {
// e.g., <tenant:serviceBindings id="Persons" name="Persons" type="authority" version="0.1">
addAuthorities(r, ele, serviceBindingVersion);
} else if (r.isType(RECORD_TYPE_USERDATA)) {
serviceBindingsElement = ele.addElement(new QName("serviceBindings", nstenant));
serviceBindingsElement.addAttribute("id", r.getServicesTenantPl());
serviceBindingsElement.addAttribute("name", r.getServicesTenantPl());
serviceBindingsElement.addAttribute("type", SERVICES_BINDING_TYPE_SECURITY);
serviceBindingsElement.addAttribute("version", serviceBindingVersion);
addServiceBinding(r, serviceBindingsElement, nsservices, false, serviceBindingVersion);
} else if (r.isType(RECORD_TYPE_AUTHORIZATIONDATA)) {
// ignore at the moment as they are so non standard
// addAuthorization(r,ele);
log.debug(String.format("Config Generation: '%s' - Ignoring record '%s:%s' at the moment as it is of type '%s' and so non-standard", getConfigFile().getName(), tenantName, r.getRecordName(), RECORD_TYPE_AUTHORIZATIONDATA));
} else {
// Should never get here
log.warn(String.format("Config Generation: '%s' - Record '%s.%s' is of an unknown type so we could not create a service binding for it.", getConfigFile().getName(), tenantName, recordName));
}
//
if (log.isDebugEnabled() == true) {
Element bindingsForRecord = serviceBindingsElement;
if (bindingsForRecord != null && !r.isType(RECORD_TYPE_AUTHORITY)) {
this.debugWriteToFile(r, bindingsForRecord, false);
}
}
} else {
log.trace(String.format("Config Generation: '%s' - Skipping record '%s' because it does not require a service binding.", getConfigFile().getName(), recordName));
}
}
return doc.asXML();
}
use of org.collectionspace.chain.csp.schema.Record in project application by collectionspace.
the class ServiceBindingsGeneration method addServiceProperty.
/*
* Added an element like the following to the passed in "props" element.
*
* <types:item xmlns:types="http://collectionspace.org/services/config/types">
* <types:key>authRef</types:key>
* <types:value>borrower</types:value>
* </types:item>
*/
private void addServiceProperty(Element props, FieldSet fieldSet, String keyName, Namespace types, boolean isAuthority) {
// <item>
Element itemElement = props.addElement(new QName("item", types));
// <key>
Element keyElement = itemElement.addElement(new QName("key", types));
keyElement.addText(keyName);
// <value>
Element valueElement = itemElement.addElement(new QName("value", types));
String fieldPath = this.getFullyQualifiedFieldPath(fieldSet);
Record record = fieldSet.getRecord();
if (fieldSet.shouldSchemaQualify() == true) {
String schemaName = record.getServicesSchemaName(fieldSet.getSection());
fieldPath = schemaName + ":" + fieldPath;
}
valueElement.addText(fieldPath);
}
Aggregations