package org.nuxeo.mule.metadata; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.codehaus.jackson.JsonNode; import org.mule.common.metadata.DefaultMetaData; import org.mule.common.metadata.DefaultMetaDataKey; import org.mule.common.metadata.MetaData; import org.mule.common.metadata.MetaDataKey; import org.mule.common.metadata.MetaDataModel; import org.mule.common.metadata.builder.DefaultMetaDataBuilder; import org.mule.common.metadata.builder.DynamicObjectBuilder; import org.mule.common.metadata.datatype.DataType; import org.nuxeo.ecm.automation.client.Session; import org.nuxeo.ecm.automation.client.jaxrs.impl.HttpAutomationClient; /** * For testing purpose, this implementation is hard-coded and not wired to a REST API * * @author <a href="mailto:tdelprat@nuxeo.com">Tiry</a> * */ public class MetaDataIntrospector { protected static final String DOC_PREFIX = "DOC_"; protected static final String DATAMODEL_PREFIX = "DM_"; protected TypeDefinitionFecther fetcher; public MetaDataIntrospector(Session session) { if (session!=null) { fetcher = new TypeDefinitionFecther((HttpAutomationClient) session.getClient()); } else { // XXX tests ! fetcher = new TypeDefinitionFecther(null); } } public List<String> getDocTypes() { return fetcher.getDocTypesNames(); } public List<MetaDataKey> getMuleTypes() { List<MetaDataKey> types = new ArrayList<MetaDataKey>(); for (String docType : getDocTypes()) { types.add(new DefaultMetaDataKey(docType, docType, false)); } Collections.sort(types); return types; } public MetaData getMuleTypeMetaData(String key) { DynamicObjectBuilder dynamicObject = new DefaultMetaDataBuilder().createDynamicObject(key); String targetDocType = key; buildMuleDocTypeMetaDataModel(targetDocType, dynamicObject); MetaDataModel model = dynamicObject.build(); return new DefaultMetaData(model); } protected void buildMuleDocTypeMetaDataModel(String docType, DynamicObjectBuilder dynamicObject) { dynamicObject.addSimpleField(DataSenseHelper.getDataSenseFieldName("ecm","path"), getDataType("string")); dynamicObject.addSimpleField(DataSenseHelper.getDataSenseFieldName("ecm","state"), getDataType("string")); dynamicObject.addSimpleField(DataSenseHelper.getDataSenseFieldName("ecm","repository"), getDataType("string")); dynamicObject.addSimpleField(DataSenseHelper.getDataSenseFieldName("ecm", "id"), getDataType("string")); dynamicObject.addSimpleField(DataSenseHelper.getDataSenseFieldName("ecm", "type"), getDataType("string")); buildMuleDataModelMetaDataModel(docType, dynamicObject); } protected void buildMuleDataModelMetaDataModel(String docType, DynamicObjectBuilder dynamicObject) { for (String schema : fetcher.getSchemasForDocType(docType)) { mapSchema(dynamicObject, schema); } } public DataType getDataType(String nxFieldType) { if ("date".equalsIgnoreCase(nxFieldType)) { return DataType.DATE_TIME; } if ("long".equalsIgnoreCase(nxFieldType)) { return DataType.LONG; } if ("integer".equalsIgnoreCase(nxFieldType)) { return DataType.INTEGER; } if ("blob".equalsIgnoreCase(nxFieldType)) { return DataType.STRING; } // XXX return DataType.STRING; } protected void buildSchemaFields(String schemaName, DynamicObjectBuilder dynamicObject) { JsonNode schema = fetcher.getSchema(schemaName); JsonNode prefixNode = schema.get("@prefix"); String prefix = schemaName; if (prefixNode!=null) { prefix = prefixNode.getTextValue(); } if (prefix==null || prefix.isEmpty()) { prefix = schemaName; } Iterator<String> fieldNamesIt = schema.getFieldNames(); while (fieldNamesIt.hasNext()) { String fieldName = fieldNamesIt.next(); if (!fieldName.startsWith("@")) { JsonNode field = schema.get(fieldName); addField(prefix, fieldName, field, dynamicObject); } } } protected void addField(String prefix, String name , JsonNode fieldNode, DynamicObjectBuilder dynamicObject) { String type = fieldNode.getTextValue(); JsonNode subFields = null; if (type==null && !fieldNode.isTextual()) { type = fieldNode.get("type").getTextValue(); subFields = fieldNode.get("fields"); } boolean multiValued = false; if (type.endsWith("[]")) { multiValued=true; type = type.substring(0, type.length()-2); } if ("blob".equals(type)) { DynamicObjectBuilder blobField = dynamicObject.addDynamicObjectField(DataSenseHelper.getDataSenseFieldName(prefix, name)); blobField.addSimpleField("encoding", DataType.STRING); blobField.addSimpleField("mime-type", DataType.STRING); blobField.addSimpleField("name", DataType.STRING); blobField.addSimpleField("length", DataType.LONG); blobField.addSimpleField("digest", DataType.STRING); blobField.addSimpleField("data", DataType.STRING); return; } if (subFields!=null) { DynamicObjectBuilder cplxField = null; if (multiValued) { cplxField = dynamicObject.addListOfDynamicObjectField(DataSenseHelper.getDataSenseFieldName(prefix, name)).addDynamicObjectField("item"); } else { cplxField = dynamicObject.addDynamicObjectField(DataSenseHelper.getDataSenseFieldName(prefix, name)); } Iterator<String> fnames = subFields.getFieldNames(); while (fnames.hasNext()) { String subFieldName = fnames.next(); JsonNode subfield = subFields.get(subFieldName); addField(prefix, subFieldName, subfield, cplxField); //addField(prefix, name + "/" + subFieldName, subfield, cplxField); } } else { if (multiValued) { dynamicObject.addListOfDynamicObjectField(DataSenseHelper.getDataSenseFieldName(prefix, name)).addSimpleField("item", getDataType(type)); } else { dynamicObject.addSimpleField(DataSenseHelper.getDataSenseFieldName(prefix, name), getDataType(type)); } } } protected void mapSchema(DynamicObjectBuilder dynamicObject, String schemaName) { buildSchemaFields(schemaName, dynamicObject); } }