package com.marklogic.client.xcc; import com.marklogic.client.document.DocumentWriteOperation; import com.marklogic.client.io.*; import com.marklogic.client.io.marker.AbstractWriteHandle; import com.marklogic.client.io.marker.DocumentMetadataWriteHandle; import com.marklogic.xcc.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.HashSet; import java.util.Set; public class DefaultDocumentWriteOperationAdapter implements DocumentWriteOperationAdapter { private final static Logger logger = LoggerFactory.getLogger(DefaultDocumentWriteOperationAdapter.class); @Override public Content adapt(DocumentWriteOperation operation) { String uri = operation.getUri(); ContentCreateOptions options = adaptMetadata(operation.getMetadata()); AbstractWriteHandle handle = operation.getContent(); if (handle instanceof StringHandle) { return ContentFactory.newContent(uri, ((StringHandle) handle).get(), options); } else if (handle instanceof FileHandle) { return ContentFactory.newContent(uri, ((FileHandle) handle).get(), options); } else if (handle instanceof BytesHandle) { return ContentFactory.newContent(uri, ((BytesHandle) handle).get(), options); } else if (handle instanceof InputStreamHandle) { try { return ContentFactory.newContent(uri, ((InputStreamHandle) handle).get(), options); } catch (IOException e) { throw new RuntimeException("Unable to read content input stream: " + e.getMessage(), e); } } else if (handle instanceof DOMHandle) { return ContentFactory.newContent(uri, ((DOMHandle) handle).get(), options); } else throw new IllegalArgumentException("No support yet for content class: " + handle.getClass().getName()); } /** * TODO Only adapts collections, quality, format, and permissions so far. * * @param handle * @return */ protected ContentCreateOptions adaptMetadata(DocumentMetadataWriteHandle handle) { ContentCreateOptions options = new ContentCreateOptions(); if (handle instanceof DocumentMetadataHandle) { DocumentMetadataHandle metadata = (DocumentMetadataHandle) handle; options.setQuality(metadata.getQuality()); options.setCollections(metadata.getCollections().toArray(new String[]{})); adaptPermissions(options, metadata); adaptFormat(options, metadata); } else { logger.warn("Only supports DocumentMetadataHandle; unsupported metadata class: " + handle.getClass().getName()); } return options; } /** * The REST API Format class has a "getDefaultMimetype" method on it, but there doesn't appear to be anything * useful to do with that for XCC. So we just do a simple translation from Format to DocumentFormat. * * @param options * @param metadata */ protected void adaptFormat(ContentCreateOptions options, DocumentMetadataHandle metadata) { Format format = metadata.getFormat(); DocumentFormat xccFormat = null; if (format != null) { if (Format.BINARY.equals(format)) { xccFormat = DocumentFormat.BINARY; } else if (Format.JSON.equals(format)) { xccFormat = DocumentFormat.JSON; } else if (Format.TEXT.equals(format)) { xccFormat = DocumentFormat.TEXT; } else if (Format.XML.equals(format)) { xccFormat = DocumentFormat.XML; } else if (Format.UNKNOWN.equals(format)) { xccFormat = DocumentFormat.NONE; } else if (logger.isDebugEnabled()) { logger.debug("Unsupported format, can't adapt to an XCC DocumentFormat; " + format.toString()); } } if (xccFormat != null) { if (logger.isDebugEnabled()) { logger.debug("Adapted REST format " + format + " to XCC format: " + xccFormat.toString()); } options.setFormat(xccFormat); } } protected void adaptPermissions(ContentCreateOptions options, DocumentMetadataHandle metadata) { Set<ContentPermission> contentPermissions = new HashSet<>(); DocumentMetadataHandle.DocumentPermissions permissions = metadata.getPermissions(); for (String role : permissions.keySet()) { for (DocumentMetadataHandle.Capability capability : permissions.get(role)) { ContentCapability contentCapability; if (DocumentMetadataHandle.Capability.EXECUTE.equals(capability)) { contentCapability = ContentCapability.EXECUTE; } else if (DocumentMetadataHandle.Capability.INSERT.equals(capability)) { contentCapability = ContentCapability.INSERT; } else if (DocumentMetadataHandle.Capability.READ.equals(capability)) { contentCapability = ContentCapability.READ; } else if (DocumentMetadataHandle.Capability.UPDATE.equals(capability)) { contentCapability = ContentCapability.UPDATE; } else throw new IllegalArgumentException("Unrecognized permission capability: " + capability); contentPermissions.add(new ContentPermission(contentCapability, role)); } } options.setPermissions(contentPermissions.toArray(new ContentPermission[]{})); } }