From: Sanjay Dalal Date: Thu, 18 Feb 2010 20:38:08 +0000 (+0000) Subject: NOJIRA added capability to read input for JAXB object from a file(in classpath)/stream. X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=7d4fa6d851d28cde46218be29553e3526ba85d62;p=tmp%2Fjakarta-migration.git NOJIRA added capability to read input for JAXB object from a file(in classpath)/stream. Added testCambridge.xml test data to use from createFromFile test test: collectionobject tests against local server and against jupiter.collectionspace.org M client/src/main/java/org/collectionspace/services/client/test/AbstractServiceTestImpl.java M client/src/main/java/org/collectionspace/services/client/AbstractServiceClientImpl.java M collectionobject/client/src/test/java/org/collectionspace/services/client/test/CollectionObjectServiceTest.java A collectionobject/client/src/test/resources/test-data A collectionobject/client/src/test/resources/test-data/testCambridge.xml --- diff --git a/services/client/src/main/java/org/collectionspace/services/client/AbstractServiceClientImpl.java b/services/client/src/main/java/org/collectionspace/services/client/AbstractServiceClientImpl.java index 8e02da3da..12dc78a45 100644 --- a/services/client/src/main/java/org/collectionspace/services/client/AbstractServiceClientImpl.java +++ b/services/client/src/main/java/org/collectionspace/services/client/AbstractServiceClientImpl.java @@ -123,8 +123,12 @@ public abstract class AbstractServiceClientImpl implements CollectionSpaceClient if(spec != null && !"".equals(spec)){ properties.setProperty(URL_PROPERTY, spec); } + spec = properties.getProperty(URL_PROPERTY); url = new URL(spec); + if(logger.isInfoEnabled()){ + logger.info("readProperties() using url=" + url); + } String auth = System.getProperty(AUTH_PROPERTY); if(auth != null && !"".equals(auth)){ diff --git a/services/client/src/main/java/org/collectionspace/services/client/test/AbstractServiceTestImpl.java b/services/client/src/main/java/org/collectionspace/services/client/test/AbstractServiceTestImpl.java index 88e01f77f..dc2826386 100644 --- a/services/client/src/main/java/org/collectionspace/services/client/test/AbstractServiceTestImpl.java +++ b/services/client/src/main/java/org/collectionspace/services/client/test/AbstractServiceTestImpl.java @@ -24,6 +24,8 @@ package org.collectionspace.services.client.test; import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.InputStream; import java.io.StringWriter; import java.lang.reflect.Method; import java.util.ArrayList; @@ -61,10 +63,10 @@ import org.slf4j.LoggerFactory; public abstract class AbstractServiceTestImpl implements ServiceTest { private final Logger logger = - LoggerFactory.getLogger(AbstractServiceTestImpl.class); + LoggerFactory.getLogger(AbstractServiceTestImpl.class); // A base-level client, used (only) to obtain the base service URL. protected static final TestServiceClient serviceClient = - new TestServiceClient(); + new TestServiceClient(); // A resource identifier believed to be non-existent in actual use, // used when testing service calls that reference non-existent resources. protected final String NON_EXISTENT_ID = createNonExistentIdentifier(); @@ -84,11 +86,11 @@ public abstract class AbstractServiceTestImpl implements ServiceTest { ""; // Note: this constant is intentionally missing its last angle bracket. protected final static String MALFORMED_XML_DATA = - XML_DECLARATION + - "wrong schema contentswrong schema contentswrong schema contents"; + XML_DECLARATION + + "wrong schema contents"; // A MIME media type character set designation for the entity bodies // of PUT and POST requests. Set this to null to avoid adding a character // set attribute to the MIME type in the "Content-Type:" HTTP header. @@ -97,16 +99,15 @@ public abstract class AbstractServiceTestImpl implements ServiceTest { // --------------------------------------------------------------- // CRUD tests : CREATE tests // --------------------------------------------------------------- - // Success outcomes @Override public void create(String testName) throws Exception { } protected void setupCreate() { - setupCreate("Create"); + setupCreate("Create"); } - + protected void setupCreate(String label) { clearSetup(); // Expected status code: 201 Created @@ -123,17 +124,15 @@ public abstract class AbstractServiceTestImpl implements ServiceTest { public abstract void createList(String testName) throws Exception; // No setup required for createList() - // Failure outcomes - @Override public abstract void createWithEmptyEntityBody(String testName) - throws Exception; + throws Exception; protected void setupCreateWithEmptyEntityBody() { - setupCreateWithEmptyEntityBody("CreateWithEmptyEntityBody"); + setupCreateWithEmptyEntityBody("CreateWithEmptyEntityBody"); } - + protected void setupCreateWithEmptyEntityBody(String label) { clearSetup(); EXPECTED_STATUS_CODE = Response.Status.BAD_REQUEST.getStatusCode(); @@ -141,15 +140,15 @@ public abstract class AbstractServiceTestImpl implements ServiceTest { if (logger.isDebugEnabled()) { banner(label); } - } + } @Override public abstract void createWithMalformedXml(String testName) throws Exception; protected void setupCreateWithMalformedXml() { - setupCreateWithMalformedXml("CreateWithMalformedXml"); + setupCreateWithMalformedXml("CreateWithMalformedXml"); } - + protected void setupCreateWithMalformedXml(String label) { clearSetup(); // Expected status code: 400 Bad Request @@ -164,9 +163,9 @@ public abstract class AbstractServiceTestImpl implements ServiceTest { public abstract void createWithWrongXmlSchema(String testName) throws Exception; protected void setupCreateWithWrongXmlSchema() { - setupCreateWithWrongXmlSchema("CreateWithWrongXmlSchema"); + setupCreateWithWrongXmlSchema("CreateWithWrongXmlSchema"); } - + protected void setupCreateWithWrongXmlSchema(String label) { clearSetup(); // Expected status code: 400 Bad Request @@ -180,15 +179,14 @@ public abstract class AbstractServiceTestImpl implements ServiceTest { // --------------------------------------------------------------- // CRUD tests : READ tests // --------------------------------------------------------------- - // Success outcomes @Override public abstract void read(String testName) throws Exception; protected void setupRead() { - setupRead("Read"); + setupRead("Read"); } - + protected void setupRead(String label) { clearSetup(); // Expected status code: 200 OK @@ -204,7 +202,7 @@ public abstract class AbstractServiceTestImpl implements ServiceTest { public abstract void readNonExistent(String testName) throws Exception; protected void setupReadNonExistent() { - setupReadNonExistent("ReadNonExistent"); + setupReadNonExistent("ReadNonExistent"); } protected void setupReadNonExistent(String label) { @@ -220,15 +218,14 @@ public abstract class AbstractServiceTestImpl implements ServiceTest { // --------------------------------------------------------------- // CRUD tests : READ (list, or multiple) tests // --------------------------------------------------------------- - // Success outcomes @Override public abstract void readList(String testName) throws Exception; protected void setupReadList() { - setupReadList("ReadList"); + setupReadList("ReadList"); } - + protected void setupReadList(String label) { clearSetup(); // Expected status code: 200 OK @@ -241,19 +238,17 @@ public abstract class AbstractServiceTestImpl implements ServiceTest { // Failure outcomes // None tested at present. - // --------------------------------------------------------------- // CRUD tests : UPDATE tests // --------------------------------------------------------------- - // Success outcomes @Override public abstract void update(String testName) throws Exception; protected void setupUpdate() { - setupUpdate("Update"); + setupUpdate("Update"); } - + protected void setupUpdate(String label) { clearSetup(); // Expected status code: 200 OK @@ -269,9 +264,9 @@ public abstract class AbstractServiceTestImpl implements ServiceTest { public abstract void updateWithEmptyEntityBody(String testName) throws Exception; protected void setupUpdateWithEmptyEntityBody() { - setupUpdateWithEmptyEntityBody("UpdateWithEmptyEntityBody"); + setupUpdateWithEmptyEntityBody("UpdateWithEmptyEntityBody"); } - + protected void setupUpdateWithEmptyEntityBody(String label) { clearSetup(); // Expected status code: 400 Bad Request @@ -286,9 +281,9 @@ public abstract class AbstractServiceTestImpl implements ServiceTest { public abstract void updateWithMalformedXml(String testName) throws Exception; protected void setupUpdateWithMalformedXml() { - setupUpdateWithMalformedXml("UpdateWithMalformedXml"); + setupUpdateWithMalformedXml("UpdateWithMalformedXml"); } - + protected void setupUpdateWithMalformedXml(String label) { clearSetup(); // Expected status code: 400 Bad Request @@ -303,9 +298,9 @@ public abstract class AbstractServiceTestImpl implements ServiceTest { public abstract void updateWithWrongXmlSchema(String testName) throws Exception; protected void setupUpdateWithWrongXmlSchema() { - setupUpdateWithWrongXmlSchema("UpdateWithWrongXmlSchema"); + setupUpdateWithWrongXmlSchema("UpdateWithWrongXmlSchema"); } - + protected void setupUpdateWithWrongXmlSchema(String label) { clearSetup(); // Expected status code: 400 Bad Request @@ -320,9 +315,9 @@ public abstract class AbstractServiceTestImpl implements ServiceTest { public abstract void updateNonExistent(String testName) throws Exception; protected void setupUpdateNonExistent() { - setupUpdateNonExistent("UpdateNonExistent"); + setupUpdateNonExistent("UpdateNonExistent"); } - + protected void setupUpdateNonExistent(String label) { clearSetup(); // Expected status code: 404 Not Found @@ -336,15 +331,14 @@ public abstract class AbstractServiceTestImpl implements ServiceTest { // --------------------------------------------------------------- // CRUD tests : DELETE tests // --------------------------------------------------------------- - // Success outcomes @Override public abstract void delete(String testName) throws Exception; protected void setupDelete() { - setupDelete("Delete"); + setupDelete("Delete"); } - + protected void setupDelete(String label) { clearSetup(); // Expected status code: 200 OK @@ -360,9 +354,9 @@ public abstract class AbstractServiceTestImpl implements ServiceTest { public abstract void deleteNonExistent(String testName) throws Exception; protected void setupDeleteNonExistent() { - setupDeleteNonExistent("DeleteNonExistent"); + setupDeleteNonExistent("DeleteNonExistent"); } - + protected void setupDeleteNonExistent(String label) { clearSetup(); // Expected status code: 404 Not Found @@ -394,10 +388,9 @@ public abstract class AbstractServiceTestImpl implements ServiceTest { * * @return The common part name for the service request. */ -/* + /* public String getCommonPartName(); -*/ - + */ // --------------------------------------------------------------- // Utility methods // --------------------------------------------------------------- @@ -410,21 +403,21 @@ public abstract class AbstractServiceTestImpl implements ServiceTest { REQUEST_TYPE = ServiceRequestType.NON_EXISTENT; } - /** - * Returns the name of the currently running test. - * - * Note: although the return type is listed as Object[][], - * this method instead returns a String. - * - * @param m The currently running test method. - * - * @return The name of the currently running test method. - */ - @DataProvider(name="testName") - public static Object[][] testName(Method m){ + /** + * Returns the name of the currently running test. + * + * Note: although the return type is listed as Object[][], + * this method instead returns a String. + * + * @param m The currently running test method. + * + * @return The name of the currently running test method. + */ + @DataProvider(name = "testName") + public static Object[][] testName(Method m) { return new Object[][]{ - new Object[] { m.getName() } - }; + new Object[]{m.getName()} + }; } /** @@ -440,10 +433,10 @@ public abstract class AbstractServiceTestImpl implements ServiceTest { * @return An error message. */ protected String invalidStatusCodeMessage( - ServiceRequestType requestType, int statusCode) { - return "Status code '" + statusCode + - "' in response is NOT within the expected set: " + - requestType.validStatusCodesAsString(); + ServiceRequestType requestType, int statusCode) { + return "Status code '" + statusCode + + "' in response is NOT within the expected set: " + + requestType.validStatusCodesAsString(); } /** @@ -483,21 +476,21 @@ public abstract class AbstractServiceTestImpl implements ServiceTest { */ protected int submitRequest(String method, String url) { int statusCode = 0; - try{ + try { TestServiceClient client = new TestServiceClient(); - if(method.equals(javax.ws.rs.HttpMethod.DELETE)){ + if (method.equals(javax.ws.rs.HttpMethod.DELETE)) { DeleteMethod deleteMethod = new DeleteMethod(url); statusCode = client.getHttpClient().executeMethod(deleteMethod); - }else if(method.equals(javax.ws.rs.HttpMethod.GET)){ + } else if (method.equals(javax.ws.rs.HttpMethod.GET)) { GetMethod getMethod = new GetMethod(url); statusCode = client.getHttpClient().executeMethod(getMethod); - }else{ + } else { // Do nothing - leave status code at default value. } - }catch(Exception e){ + } catch (Exception e) { logger.error( - "Exception during HTTP " + method + " request to " + - url + ":", e); + "Exception during HTTP " + method + " request to " + + url + ":", e); } return statusCode; } @@ -520,27 +513,27 @@ public abstract class AbstractServiceTestImpl implements ServiceTest { protected int submitRequest(String method, String url, String mediaType, String entityStr) { int statusCode = 0; - try{ + try { TestServiceClient client = new TestServiceClient(); - if(method.equals(javax.ws.rs.HttpMethod.POST)){ + if (method.equals(javax.ws.rs.HttpMethod.POST)) { StringRequestEntity entityBody = - new StringRequestEntity(mediaType, entityStr, NULL_CHARSET); + new StringRequestEntity(mediaType, entityStr, NULL_CHARSET); PostMethod postMethod = new PostMethod(url); postMethod.setRequestEntity(entityBody); statusCode = client.getHttpClient().executeMethod(postMethod); - }else if(method.equals(javax.ws.rs.HttpMethod.PUT)){ + } else if (method.equals(javax.ws.rs.HttpMethod.PUT)) { StringRequestEntity entityBody = - new StringRequestEntity(mediaType, entityStr, NULL_CHARSET); + new StringRequestEntity(mediaType, entityStr, NULL_CHARSET); PutMethod putMethod = new PutMethod(url); putMethod.setRequestEntity(entityBody); statusCode = client.getHttpClient().executeMethod(putMethod); - }else{ + } else { // Do nothing - leave status code at default value. } - }catch(Exception e){ + } catch (Exception e) { logger.error( - "Exception during HTTP " + method + " request to " + - url + ":", e); + "Exception during HTTP " + method + " request to " + + url + ":", e); } return statusCode; } @@ -549,18 +542,18 @@ public abstract class AbstractServiceTestImpl implements ServiceTest { protected String extractId(ClientResponse res) { MultivaluedMap mvm = res.getMetadata(); String uri = (String) ((ArrayList) mvm.get("Location")).get(0); - if(logger.isDebugEnabled()){ + if (logger.isDebugEnabled()) { logger.debug("extractId:uri=" + uri); } String[] segments = uri.split("/"); String id = segments[segments.length - 1]; - if(logger.isDebugEnabled()){ + if (logger.isDebugEnabled()) { logger.debug("id=" + id); } return id; } - protected String createIdentifier() { + protected String createIdentifier() { long identifier = System.currentTimeMillis(); return Long.toString(identifier); } @@ -570,70 +563,70 @@ public abstract class AbstractServiceTestImpl implements ServiceTest { } protected Object extractPart(MultipartInput input, String label, - Class clazz) throws Exception { + Class clazz) throws Exception { Object obj = null; String partLabel = ""; List parts = input.getParts(); if (parts.size() == 0) { logger.warn("No parts found in multipart body."); } - if(logger.isDebugEnabled()){ + if (logger.isDebugEnabled()) { logger.debug("Parts:"); - for(InputPart part : parts){ - partLabel = part.getHeaders().getFirst("label"); - logger.debug("part = " + partLabel); + for (InputPart part : parts) { + partLabel = part.getHeaders().getFirst("label"); + logger.debug("part = " + partLabel); } } boolean partLabelMatched = false; - for(InputPart part : parts){ + for (InputPart part : parts) { partLabel = part.getHeaders().getFirst("label"); - if(label.equalsIgnoreCase(partLabel)){ + if (label.equalsIgnoreCase(partLabel)) { partLabelMatched = true; - if(logger.isDebugEnabled()){ + if (logger.isDebugEnabled()) { logger.debug("found part" + partLabel); } String partStr = part.getBodyAsString(); if (partStr == null || partStr.trim().isEmpty()) { logger.warn("Part '" + label + "' in multipart body is empty."); } else { - if (logger.isDebugEnabled()){ + if (logger.isDebugEnabled()) { logger.debug("extracted part as str=\n" + partStr); } obj = part.getBody(clazz, null); - if(logger.isDebugEnabled()){ + if (logger.isDebugEnabled()) { logger.debug("extracted part as obj=\n", - objectAsXmlString(obj, clazz)); + objectAsXmlString(obj, clazz)); } } break; } } - if (! partLabelMatched) { + if (!partLabelMatched) { logger.warn("Could not find part '" + label + "' in multipart body."); - // In the event that getBodyAsString() or getBody(), above, do *not* - // throw an IOException, but getBody() nonetheless retrieves a null object. - // This *may* be unreachable. + // In the event that getBodyAsString() or getBody(), above, do *not* + // throw an IOException, but getBody() nonetheless retrieves a null object. + // This *may* be unreachable. } else if (obj == null) { - logger.warn("Could not extract part '" + label + - "' in multipart body as an object."); + logger.warn("Could not extract part '" + label + + "' in multipart body as an object."); } return obj; } protected Object getPartObject(String partStr, Class clazz) - throws JAXBException { + throws JAXBException { JAXBContext jc = JAXBContext.newInstance(clazz); ByteArrayInputStream bais = null; Object obj = null; - try{ + try { bais = new ByteArrayInputStream(partStr.getBytes()); Unmarshaller um = jc.createUnmarshaller(); obj = um.unmarshal(bais); - }finally{ - if(bais != null){ - try{ + } finally { + if (bais != null) { + try { bais.close(); - }catch(Exception e){ + } catch (Exception e) { } } } @@ -643,24 +636,57 @@ public abstract class AbstractServiceTestImpl implements ServiceTest { // @TODO Some of the methods below may be candidates // to be moved to a utilities module, suitable for use // by both client-side and server-side code. - protected String objectAsXmlString(Object o, Class clazz) { StringWriter sw = new StringWriter(); - try{ + try { JAXBContext jc = JAXBContext.newInstance(clazz); Marshaller m = jc.createMarshaller(); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); m.marshal(o, sw); - }catch(Exception e){ + } catch (Exception e) { e.printStackTrace(); } return sw.toString(); } + + /** + * getObjectFromFile get object of given class from given file (in classpath) + * @param jaxbClass + * @param fileName of the file to read to construct the object + * @return + * @throws Exception + */ + protected Object getObjectFromFile(Class jaxbClass, String fileName) + throws Exception { + + JAXBContext context = JAXBContext.newInstance(jaxbClass); + Unmarshaller unmarshaller = context.createUnmarshaller(); + //note: setting schema to null will turn validator off + unmarshaller.setSchema(null); + ClassLoader tccl = Thread.currentThread().getContextClassLoader(); + InputStream is = tccl.getResourceAsStream(fileName); + return getObjectFromStream(jaxbClass, is); + } + + /** + * getObjectFromStream get object of given class from given inputstream + * @param jaxbClass + * @param is stream to read to construct the object + * @return + * @throws Exception + */ + protected Object getObjectFromStream(Class jaxbClass, InputStream is) throws Exception { + JAXBContext context = JAXBContext.newInstance(jaxbClass); + Unmarshaller unmarshaller = context.createUnmarshaller(); + //note: setting schema to null will turn validator off + unmarshaller.setSchema(null); + return jaxbClass.cast(unmarshaller.unmarshal(is)); + } protected String mapAsString(MultivaluedMap map) { StringBuffer sb = new StringBuffer(); - for(Object entry : map.entrySet()){ + for (Object entry : map.entrySet()) { MultivaluedMap.Entry mentry = (MultivaluedMap.Entry) entry; sb.append(" name=" + mentry.getKey()); sb.append(" value=" + mentry.getValue() + "\n"); @@ -669,7 +695,7 @@ public abstract class AbstractServiceTestImpl implements ServiceTest { } protected void banner(String label) { - if(logger.isDebugEnabled()){ + if (logger.isDebugEnabled()) { logger.debug("==================================================="); logger.debug(" Test = " + label); logger.debug("==================================================="); diff --git a/services/collectionobject/client/src/test/java/org/collectionspace/services/client/test/CollectionObjectServiceTest.java b/services/collectionobject/client/src/test/java/org/collectionspace/services/client/test/CollectionObjectServiceTest.java index 5c7871adb..f534e4301 100644 --- a/services/collectionobject/client/src/test/java/org/collectionspace/services/client/test/CollectionObjectServiceTest.java +++ b/services/collectionobject/client/src/test/java/org/collectionspace/services/client/test/CollectionObjectServiceTest.java @@ -116,6 +116,37 @@ public class CollectionObjectServiceTest extends AbstractServiceTestImpl { allResourceIdsCreated.add(extractId(res)); } + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class) + public void createFromXml(String testName) throws Exception { + + // Perform setup, such as initializing the type of service request + // (e.g. CREATE, DELETE), its valid and expected status codes, and + // its associated HTTP method name (e.g. POST, DELETE). + setupCreate(testName); + + // Submit the request to the service and store the response. + String identifier = createIdentifier(); + MultipartOutput multipart = + createCollectionObjectInstanceFromXml(client.getCommonPartName(), + "test-data/testCambridge.xml"); + ClientResponse res = client.create(multipart); + int statusCode = res.getStatus(); + + // Check the status code of the response: does it match + // the expected response(s)? + // + // Specifically: + // Does it fall within the set of valid status codes? + // Does it exactly match the expected status code? + if (logger.isDebugEnabled()) { + logger.debug(testName + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + allResourceIdsCreated.add(extractId(res)); + } + /* (non-Javadoc) * @see org.collectionspace.services.client.test.ServiceTest#createList() */ @@ -723,7 +754,7 @@ public class CollectionObjectServiceTest extends AbstractServiceTestImpl { } multivalue = !multivalue; //FIXME: Title does not need to be set. - collectionObject.setTitle("acoward"); + collectionObject.setTitle("atitle"); collectionObject.setResponsibleDepartments(deptList); collectionObject.setObjectNumber(objectNumber); collectionObject.setOtherNumber("urn:org.walkerart.id:123"); @@ -771,6 +802,26 @@ public class CollectionObjectServiceTest extends AbstractServiceTestImpl { } + private MultipartOutput createCollectionObjectInstanceFromXml(String commonPartName, + String commonPartFileName) throws Exception { + + CollectionobjectsCommon collectionObject = (CollectionobjectsCommon) getObjectFromFile(CollectionobjectsCommon.class, + commonPartFileName); + MultipartOutput multipart = new MultipartOutput(); + OutputPart commonPart = multipart.addPart(collectionObject, + MediaType.APPLICATION_XML_TYPE); + commonPart.getHeaders().add("label", commonPartName); + + if (logger.isDebugEnabled()) { + logger.debug("to be created, collectionobject common"); + logger.debug(objectAsXmlString(collectionObject, + CollectionobjectsCommon.class)); + } + + return multipart; + + } + private String getNHPartName() { return "collectionobjects_naturalhistory"; } diff --git a/services/collectionobject/client/src/test/resources/test-data/testCambridge.xml b/services/collectionobject/client/src/test/resources/test-data/testCambridge.xml new file mode 100644 index 000000000..8f87e621c --- /dev/null +++ b/services/collectionobject/client/src/test/resources/test-data/testCambridge.xml @@ -0,0 +1,124 @@ + + + + + objectNumber + XXX + otherNumberType + briefDescription + comments + distFeatures + numberOfObjects + objectName + objectNameCurrency + XXX + objectNameNote + objectNameSystem + objectNameType + objectNameLanguage + + + + title + objectTitleLanguage + titleTranslation + titleType + age + ageQualifier + ageUnit + color + contentActivity + contentConcept + XXX + contentDescription + contentEventName + contentEventNameType + contentNote + contentLanguage + contentObject + contentObjectType + contentOrganization + contentOther + contentOtherType + contentPeople + contentPerson + contentPlace + contentPosition + XXX + copyNumber + dimension + dimensionMeasuredPart + +dimensionMeasurementUnit + dimensionValue + XXX + +dimensionValueQualifier + editionNumber +
form
+ inscriptionContent + inscriber + inscriptionDate + +inscriptionInterpretation + inscriptionLanguage + inscriptionMethod + inscriptionPosition + inscriptionScript + inscriptionTranslation + +inscriptionTransliteration + inscriptionType + inscriptionDescription + +inscriptionDescriptionInscriber + +inscriptionDescriptionDate + +inscriptionDescriptionInterpretation + +inscriptionDescriptionMethod + +inscriptionDescriptionPosition + +inscriptionDescriptionType + material + materialComponent + materialComponentNote + materialName + materialSource + objectStatus + phase + physicalDescription + sex + + technicalAttribute + +technicalAttributeMeasurement + +technicalAttributeMeasurementUnit + objectComponentName + +objectComponentInformation + dateAssociation + +{"level":"objectLevel","content-script":"descContentScript","content-method":"descContentMethod","otherNumber":"otherNumber"} + + +dateEarliestSingleCertainty + +dateEarlierstSingleQualifier + XXX + dateLatestCertainty + dateLatestQualifier + datePeriod + dateText +