/** * Load schema. * * @param schema the schema * @param schemaElement the schema element * @return the map * @throws Exception the exception */ @SuppressWarnings("unchecked") private static Map<String, Object> loadSchema( Schema schema, org.dom4j.Element schemaElement, ServiceContext ctx) throws Exception { String schemaName1 = schemaElement.attributeValue( ExportConstants.NAME_ATTR); // FIXME: Do we need this local var? String schemaName = schema.getName(); Map<String, Object> data = new HashMap<String, Object>(); Iterator<org.dom4j.Element> it = schemaElement.elementIterator(); while (it.hasNext()) { org.dom4j.Element element = it.next(); String name = element.getName(); Field field = schema.getField(name); if (field != null) { Object value = getElementData(element, field.getType(), ctx); data.put(name, value); } else { // FIXME: substitute an appropriate constant for "csid" below. // One potential class to which to add that constant, if it is not already // declared, might be AbstractCollectionSpaceResourceImpl - ADR 2012-09-24 if (!name.equals("csid")) { // 'csid' elements in input payloads can be safely ignored. logger.warn( "Invalid input document. No such property was found [" + name + "] in schema " + schemaName); } } } return data; }
/** * Builds the document. * * @param document the document * @param e the e * @param objectProps the object props * @throws Exception the exception */ public static void buildDocument( Document document, Element parent, Map<String, Object> objectProps, Schema schema) throws Exception { for (String prop : objectProps.keySet()) { Object value = objectProps.get(prop); if (value != null) { Field field = schema.getField(prop); // If there is no field, then we added this property to the properties, // and it must be a String (e.g., CSID) // TODO - infer the type from the type of Object, if we need more than String if (field == null) { field = new FieldImpl(new QName(prop), schema, StringType.INSTANCE); } buildProperty(document, parent, field, value); } } }
@Override public Field getField(String xpath) { checkDirty(); Field field = null; if (xpath != null && xpath.contains("/")) { // need to resolve subfields String[] properties = xpath.split("/"); Field resolvedField = getField(properties[0]); for (int x = 1; x < properties.length; x++) { if (resolvedField == null) { break; } resolvedField = getField(resolvedField, properties[x], x == properties.length - 1); } if (resolvedField != null) { field = resolvedField; } } else { field = fields.get(xpath); if (field == null) { QName qname = QName.valueOf(xpath); String prefix = qname.getPrefix(); Schema schema = getSchemaFromPrefix(prefix); if (schema == null) { // try using the name schema = getSchema(prefix); } if (schema != null) { field = schema.getField(qname.getLocalName()); if (field != null) { // map is concurrent so parallelism is ok fields.put(xpath, field); } } } } return field; }
/** Sets a value (may be complex/list) into the document at the given xpath. */ protected void setValueObject(T state, String xpath, Object value) throws PropertyException { xpath = canonicalXPath(xpath); String[] segments = xpath.split("/"); ComplexType parentType = getType(); for (int i = 0; i < segments.length; i++) { String segment = segments[i]; Field field = parentType.getField(segment); if (field == null && i == 0) { // check facets SchemaManager schemaManager = Framework.getService(SchemaManager.class); for (String facet : getFacets()) { CompositeType facetType = schemaManager.getFacet(facet); field = facetType.getField(segment); if (field != null) { break; } } } if (field == null && i == 0 && getProxySchemas() != null) { // check proxy schemas for (Schema schema : getProxySchemas()) { field = schema.getField(segment); if (field != null) { break; } } } if (field == null) { throw new PropertyNotFoundException(xpath, i == 0 ? null : "Unknown segment: " + segment); } String name = field.getName().getPrefixedName(); // normalize from segment Type type = field.getType(); // check if we have a complex list index in the next position if (i < segments.length - 1 && StringUtils.isNumeric(segments[i + 1])) { int index = Integer.parseInt(segments[i + 1]); i++; if (!type.isListType() || ((ListType) type).getFieldType().isSimpleType()) { throw new PropertyNotFoundException(xpath, "Cannot use index after segment: " + segment); } List<T> list = getChildAsList(state, name); if (index >= list.size()) { throw new PropertyNotFoundException(xpath, "Index out of bounds: " + index); } // find complex list state state = list.get(index); field = ((ListType) type).getField(); if (i == segments.length - 1) { // last segment setValueComplex(state, field, value); } else { // not last segment parentType = (ComplexType) field.getType(); } continue; } if (i == segments.length - 1) { // last segment setValueField(state, field, value); } else { // not last segment if (type.isSimpleType()) { // scalar throw new PropertyNotFoundException(xpath, "Segment must be last: " + segment); } else if (type.isComplexType()) { // complex property state = getChildForWrite(state, name, type); parentType = (ComplexType) type; } else { // list ListType listType = (ListType) type; if (listType.isArray()) { // array of scalars throw new PropertyNotFoundException(xpath, "Segment must be last: " + segment); } else { // complex list but next segment was not numeric throw new PropertyNotFoundException( xpath, "Missing list index after segment: " + segment); } } } } }
/** Gets a value (may be complex/list) from the document at the given xpath. */ protected Object getValueObject(T state, String xpath) throws PropertyException { xpath = canonicalXPath(xpath); String[] segments = xpath.split("/"); /* * During this loop state may become null if we read an uninitialized complex property (DBS), in that case the * code must treat it as reading uninitialized values for its children. */ ComplexType parentType = getType(); for (int i = 0; i < segments.length; i++) { String segment = segments[i]; Field field = parentType.getField(segment); if (field == null && i == 0) { // check facets SchemaManager schemaManager = Framework.getService(SchemaManager.class); for (String facet : getFacets()) { CompositeType facetType = schemaManager.getFacet(facet); field = facetType.getField(segment); if (field != null) { break; } } } if (field == null && i == 0 && getProxySchemas() != null) { // check proxy schemas for (Schema schema : getProxySchemas()) { field = schema.getField(segment); if (field != null) { break; } } } if (field == null) { throw new PropertyNotFoundException(xpath, i == 0 ? null : "Unknown segment: " + segment); } String name = field.getName().getPrefixedName(); // normalize from segment Type type = field.getType(); // check if we have a complex list index in the next position if (i < segments.length - 1 && StringUtils.isNumeric(segments[i + 1])) { int index = Integer.parseInt(segments[i + 1]); i++; if (!type.isListType() || ((ListType) type).getFieldType().isSimpleType()) { throw new PropertyNotFoundException(xpath, "Cannot use index after segment: " + segment); } List<T> list = state == null ? Collections.emptyList() : getChildAsList(state, name); if (index >= list.size()) { throw new PropertyNotFoundException(xpath, "Index out of bounds: " + index); } // find complex list state state = list.get(index); parentType = (ComplexType) ((ListType) type).getFieldType(); if (i == segments.length - 1) { // last segment return getValueComplex(state, parentType); } else { // not last segment continue; } } if (i == segments.length - 1) { // last segment return state == null ? null : getValueField(state, field); } else { // not last segment if (type.isSimpleType()) { // scalar throw new PropertyNotFoundException(xpath, "Segment must be last: " + segment); } else if (type.isComplexType()) { // complex property state = state == null ? null : getChild(state, name, type); // here state can be null (DBS), continue loop with it, meaning uninitialized for read parentType = (ComplexType) type; } else { // list ListType listType = (ListType) type; if (listType.isArray()) { // array of scalars throw new PropertyNotFoundException(xpath, "Segment must be last: " + segment); } else { // complex list but next segment was not numeric throw new PropertyNotFoundException( xpath, "Missing list index after segment: " + segment); } } } } throw new AssertionError("not reached"); }