use of org.collectionspace.chain.csp.schema.FieldSet in project application by collectionspace.
the class MakeXsd method generateSchema.
/**
* Generates and returns and XSD schema.
*
* @param schemaName
* @param record
* @param schemaVersion
* @return
* @throws Exception
*/
private String generateSchema(String schemaName, Record record, String schemaVersion) throws Exception {
this.xsdRecord = record;
this.currentSchemaName = schemaName;
Document doc = DocumentFactory.getInstance().createDocument();
String servicesRecordPath = null;
String[] parts = null;
try {
servicesRecordPath = record.getServicesRecordPath(schemaName);
parts = servicesRecordPath.split(":", 2);
} catch (NullPointerException e) {
String msg;
if (servicesRecordPath == null) {
msg = String.format("Missing '<services-record-path>' config element declaration for schema/section '%s' in record '%s'.", schemaName, record.toString());
} else {
msg = String.format("Could not split services record path for record '%s' with schema '%s'.", record.toString(), schemaName);
}
throw new Exception(msg, e);
}
String[] rootel = parts[1].split(",");
Element root = doc.addElement(new QName("schema", new Namespace("xs", "http://www.w3.org/2001/XMLSchema")));
root.addAttribute("xmlns:ns", rootel[0]);
root.addAttribute("xmlns", rootel[0]);
root.addAttribute("targetNamespace", rootel[0]);
root.addAttribute("version", schemaVersion);
// add top level items
Namespace ns = new Namespace("xs", "http://www.w3.org/2001/XMLSchema");
for (FieldSet fs : record.getAllFieldTopLevel("")) {
try {
if (fs.getSection().equalsIgnoreCase(schemaName) == true) {
generateDataEntry(root, fs, ns, root, false);
log.trace(String.format("Generated data entry for fieldset '%s:%s' of record %s:%s", fs.getSection(), fs.getID(), schemaName, record.whoamI));
} else {
log.trace(String.format("Ignoring fieldset %s:%s of record %s:%s", fs.getSection(), fs.getID(), schemaName, record.whoamI));
}
} catch (Exception e) {
sendToErrorLog(String.format("Could not generate data entry for fieldset '%s:%s' of record %s:%s", fs.getSection(), fs.getID(), schemaName, record.whoamI), e);
throw e;
}
}
/**
* Enable this code for creating the abstract common list elements.
* generateSearchList(root, ns);
* // log.info(doc.asXML());
* // return doc.asXML();
*/
String schemaResult = doc.asXML();
return schemaResult;
}
use of org.collectionspace.chain.csp.schema.FieldSet in project application by collectionspace.
the class MakeXsd method generateDataEntry.
private void generateDataEntry(Element ele, FieldSet fs, Namespace ns, Element root, Boolean unbounded) throws Exception {
//
if (fs.isInServices() == false) {
sendToDebugLog(String.format("Field set is not part of the Services schema %s:%s", fs.getSection(), fs.getID()));
return;
}
String sectionName = fs.getSection();
String listName = fs.getServicesTag();
// to the "GroupField's" structured types -e.g., structuredData and dimension types
if (fs.isAGroupField() == true) {
String groupFieldType = generateFieldGroup(fs, ele, ns, root);
fs.setServicesType(groupFieldType);
}
if (fs.isAGroupField() && fs.isAStructureDate() == false) {
//
return;
}
if (fs instanceof Field || fs instanceof Group) {
String servicesTag = fs.getServicesTag();
if (isOrphaned(fs) == true) {
// If we have a Repeat with a single child that is a "Group" with a "ui-type=groupfield/foo" attribute.
servicesTag = fs.getParentID();
unbounded = true;
}
// <xs:element name="csid" type="xs:string"/>
Element field = ele.addElement(new QName("element", ns));
if (fs.isAGroupField() && fs.isAStructureDate() == false) {
servicesTag = fs.getServicesType();
}
field.addAttribute("name", servicesTag);
String servicesType = fs.getServicesType();
String fieldType = "xs:string";
if (servicesType != null) {
fieldType = servicesType;
}
field.addAttribute("type", fieldType);
if (unbounded == true) {
field.addAttribute("minOccurs", "0");
field.addAttribute("maxOccurs", "unbounded");
}
}
if (isRepeatType(fs) == true) {
// Has to be a Repeat class instance and not any descendant (e.g. not a Group instance)
Element fieldElement = root;
Repeat rfs = (Repeat) fs;
if (rfs.hasServicesParent()) {
// group repeatable
// <xs:element name="objectNameList" type="ns:objectNameList"/>
Element newField = ele.addElement(new QName("element", ns));
newField.addAttribute("name", rfs.getServicesParent()[0]);
String fieldType = rfs.getServicesParent()[0];
newField.addAttribute("type", FieldSet.NS + fieldType);
} else {
// single repeatable
// <xs:element name="responsibleDepartments"
// type="responsibleDepartmentList"/>
fieldElement = ele.addElement(new QName("element", ns));
fieldElement.addAttribute("name", rfs.getServicesTag());
FieldSet[] fieldSetArray = rfs.getChildren("");
if (fieldSetArray != null && fieldSetArray.length > 0) {
if (rfs.isServicesAnonymousType() == true) {
// Ends up creating an embedded anonymous complex type
listName = null;
} else {
listName = rfs.getChildren("")[0].getServicesTag() + "List";
fieldElement.addAttribute("type", FieldSet.NS + listName);
fieldElement = fieldElement.getParent();
}
} else {
// If there is no children to define the type, there better be an explicit services type declaration
String servicesType = rfs.getServicesType();
if (servicesType != null) {
fieldElement.addAttribute("type", servicesType);
} else {
sendToErrorLog("Repeat/Group fieldset child array was null or the first element was null. Field attribute name: " + fieldElement.toString());
}
}
}
generateRepeat(rfs, fieldElement, listName, ns, root);
}
}
use of org.collectionspace.chain.csp.schema.FieldSet in project application by collectionspace.
the class MakeXsd method generateFieldGroup.
/*
* This method generates an XML Schema complex type definition for "ui-type" config attributes -e.g., "groupfield/structureddate"
*/
private String generateFieldGroup(FieldSet fieldSet, Element ele, Namespace ns, Element root) throws Exception {
String fieldSetServicesType = fieldSet.getServicesType(false);
Spec spec = fieldSet.getRecord().getSpec();
// find a record that corresponds to the fieldset's service type
Record record = spec.getRecord(fieldSetServicesType);
if (record == null) {
// try again, this time try a group type
record = spec.getRecord(fieldSetServicesType);
}
if (record == null) {
String msg = String.format("Could not find parent record for field '%s'.", fieldSet.toString());
throw new Exception(msg);
}
String servicesType = record.getServicesType();
//
// Special case for backwards compat with existing "dateGroup" table/schema in Services
//
String servicesGroupType = fieldSet.getServicesGroupType(false);
if (fieldSetServicesType.equalsIgnoreCase(servicesGroupType) == false) {
servicesType = servicesGroupType;
}
if (servicesType == null) {
servicesType = fieldSetServicesType;
}
boolean definedNewType = false;
Element currentElement = ele;
Element complexElement = currentElement;
//
if (fieldSet.isAStructureDate() == true) {
@SuppressWarnings("unused") String // for debugging puposes only
parentRecordName = fieldSet.getRecord().getID();
// We'll add the structured date type def to the root/outer level
currentElement = root;
complexElement = root.addElement(new QName("complexType", ns));
complexElement.addAttribute("name", servicesType);
definedNewType = true;
Element sequenced = complexElement.addElement(new QName("sequence", ns));
currentElement = sequenced;
} else {
String msg = String.format("Not a structuredDate fieldset. Field set services type: '%s', Services type: '%s'", fieldSetServicesType, servicesType);
sendToDebugLog(msg);
}
for (FieldSet subRecordFieldSet : record.getAllFieldTopLevel("")) {
generateDataEntry(currentElement, subRecordFieldSet, ns, root, false);
}
if (definedNewType == true) {
String complexElementXSD = complexElement.asXML();
if (isValidNewType(servicesType, complexElementXSD, fieldSet.getID()) == true) {
if (isDefinedLocally(servicesType, complexElementXSD) == false) {
recordDefinedComplexTypes.put(servicesType, complexElementXSD);
sendToDebugLog(String.format("The complex type '%s' is defined as: %s", servicesType, complexElementXSD));
} else {
// No need to define this type more than once in the current schema, so remove the element we just created.
root.remove(complexElement);
sendToDebugLog(String.format("The complex type '%s' redefinition will be ingnored. Def of: %s", servicesType, complexElementXSD));
}
}
}
return servicesType;
}
use of org.collectionspace.chain.csp.schema.FieldSet in project application by collectionspace.
the class UserStorage method getPaths.
@Override
@SuppressWarnings("unchecked")
public String[] getPaths(ContextualisedStorage root, CSPRequestCredentials creds, CSPRequestCache cache, String rootPath, JSONObject restrictions) throws ExistException, UnimplementedException, UnderlyingStorageException {
try {
List<String> out = new ArrayList<String>();
Iterator rit = restrictions.keys();
StringBuffer args = new StringBuffer();
while (rit.hasNext()) {
String key = (String) rit.next();
FieldSet fs = r.getFieldTopLevel(key);
if (!(fs instanceof Field))
continue;
String filter = ((Field) fs).getServicesFilterParam();
if (filter == null)
continue;
args.append('&');
args.append(filter);
args.append('=');
args.append(URLEncoder.encode(restrictions.getString(key), "UTF-8"));
}
// pagination
String tail = args.toString();
String path = getRestrictedPath(r.getServicesURL(), restrictions, r.getServicesSearchKeyword(), tail, false, "");
ReturnedDocument doc = conn.getXMLDocument(RequestMethod.GET, path, null, creds, cache);
if (doc.getStatus() < 200 || doc.getStatus() > 399)
throw new UnderlyingStorageException("Cannot retrieve account list", doc.getStatus(), path);
Document list = doc.getDocument();
List<Node> objects = list.selectNodes(r.getServicesListPath());
for (Node object : objects) {
List<Node> fields = object.selectNodes("*");
String csid = object.selectSingleNode("csid").getText();
for (Node field : fields) {
if ("csid".equals(field.getName())) {
int idx = csid.lastIndexOf("/");
if (idx != -1)
csid = csid.substring(idx + 1);
out.add(csid);
} else if ("uri".equals(field.getName())) {
// Skip!
} else {
String json_name = view_map.get(field.getName());
if (json_name != null) {
String value = field.getText();
// XXX hack to cope with multi values
if (value == null || "".equals(value)) {
List<Node> inners = field.selectNodes("*");
for (Node n : inners) {
value += n.getText();
}
}
setGleanedValue(cache, r.getServicesURL() + "/" + csid, json_name, value);
}
}
}
}
return out.toArray(new String[0]);
} catch (ConnectionException e) {
throw new UnderlyingStorageException("Service layer exception" + e.getLocalizedMessage(), e.getStatus(), e.getUrl(), e);
} catch (UnsupportedEncodingException e) {
throw new UnderlyingStorageException("Exception building query" + e.getLocalizedMessage(), e);
} catch (JSONException e) {
throw new UnderlyingStorageException("Exception building query" + e.getLocalizedMessage(), e);
}
}
use of org.collectionspace.chain.csp.schema.FieldSet in project application by collectionspace.
the class UserStorage method getPathsJSON.
@Override
@SuppressWarnings("unchecked")
public JSONObject getPathsJSON(ContextualisedStorage root, CSPRequestCredentials creds, CSPRequestCache cache, String rootPath, JSONObject restrictions) throws ExistException, UnimplementedException, UnderlyingStorageException {
try {
JSONObject out = new JSONObject();
List<String> listitems = new ArrayList<String>();
Iterator rit = restrictions.keys();
StringBuffer args = new StringBuffer();
while (rit.hasNext()) {
String key = (String) rit.next();
FieldSet fs = r.getFieldTopLevel(key);
if (!(fs instanceof Field))
continue;
String filter = ((Field) fs).getServicesFilterParam();
if (filter == null)
continue;
args.append('&');
args.append(filter);
args.append('=');
args.append(URLEncoder.encode(restrictions.getString(key), "UTF-8"));
}
// pagination
String tail = args.toString();
String path = getRestrictedPath(r.getServicesURL(), restrictions, r.getServicesSearchKeyword(), tail, false, "");
if (r.hasSoftDeleteMethod()) {
path = softpath(path);
}
if (r.hasHierarchyUsed("screen")) {
path = hierarchicalpath(path);
}
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("Exception building query" + e.getLocalizedMessage(), e);
} catch (JSONException e) {
throw new UnderlyingStorageException("Exception building query" + e.getLocalizedMessage(), e);
}
}
Aggregations