001/* 002 * (C) Copyright 2006-2016 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Nuxeo - initial API and implementation 018 */ 019package org.nuxeo.ecm.core.api.blobholder; 020 021import java.io.IOException; 022import java.util.HashMap; 023import java.util.Map; 024import java.util.Set; 025 026import org.apache.commons.logging.Log; 027import org.apache.commons.logging.LogFactory; 028import org.nuxeo.ecm.core.api.Blob; 029import org.nuxeo.ecm.core.api.DocumentModel; 030import org.nuxeo.ecm.core.api.PropertyException; 031import org.nuxeo.ecm.core.api.adapter.DocumentAdapterFactory; 032import org.nuxeo.ecm.core.api.externalblob.ExternalBlobAdapter; 033import org.nuxeo.ecm.core.api.externalblob.ExternalBlobAdapterDescriptor; 034import org.nuxeo.runtime.api.Framework; 035import org.nuxeo.runtime.model.ComponentInstance; 036import org.nuxeo.runtime.model.DefaultComponent; 037 038/** 039 * Runtime component to manage the pluggable factory for {@link DocumentAdapterFactory}. 040 * <p> 041 * Also provides the service interface {@link BlobHolderAdapterService} 042 * 043 * @author tiry 044 */ 045public class BlobHolderAdapterComponent extends DefaultComponent implements BlobHolderAdapterService { 046 047 private static final Log log = LogFactory.getLog(BlobHolderAdapterComponent.class); 048 049 public static final String BLOBHOLDERFACTORY_EP = "BlobHolderFactory"; 050 051 public static final String EXTERNALBLOB_ADAPTER_EP = "ExternalBlobAdapter"; 052 053 protected final Map<String, BlobHolderFactory> factories = new HashMap<>(); 054 055 protected Map<String, BlobHolderFactory> factoriesByFacets = new HashMap<>(); 056 057 protected static final Map<String, ExternalBlobAdapter> externalBlobAdapters = new HashMap<>(); 058 059 @Override 060 public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 061 062 if (BLOBHOLDERFACTORY_EP.equals(extensionPoint)) { 063 BlobHolderFactoryDescriptor desc = (BlobHolderFactoryDescriptor) contribution; 064 String docType = desc.getDocType(); 065 if (docType != null) { 066 factories.put(docType, desc.getFactory()); 067 } 068 String facet = desc.getFacet(); 069 if (facet != null) { 070 factoriesByFacets.put(facet, desc.getFactory()); 071 } 072 } else if (EXTERNALBLOB_ADAPTER_EP.equals(extensionPoint)) { 073 ExternalBlobAdapterDescriptor desc = (ExternalBlobAdapterDescriptor) contribution; 074 ExternalBlobAdapter adapter = desc.getAdapter(); 075 String prefix = desc.getPrefix(); 076 if (externalBlobAdapters.containsKey(prefix)) { 077 log.info(String.format("Overriding external blob adapter with prefix '%s'", prefix)); 078 externalBlobAdapters.remove(prefix); 079 } 080 adapter.setPrefix(desc.getPrefix()); 081 adapter.setProperties(desc.getProperties()); 082 externalBlobAdapters.put(desc.getPrefix(), adapter); 083 log.info(String.format("Registered external blob adapter with prefix '%s'", prefix)); 084 } else { 085 log.error("Unknown extension point " + extensionPoint); 086 } 087 } 088 089 @Override 090 public void unregisterContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 091 } 092 093 /* for test */ 094 095 public static Set<String> getFactoryNames() { 096 return ((BlobHolderAdapterComponent) Framework.getLocalService( 097 BlobHolderAdapterService.class)).factories.keySet(); 098 } 099 100 /* Service Interface */ 101 102 @Override 103 public ExternalBlobAdapter getExternalBlobAdapterForPrefix(String prefix) { 104 return externalBlobAdapters.get(prefix); 105 } 106 107 @Override 108 public ExternalBlobAdapter getExternalBlobAdapterForUri(String uri) { 109 if (uri != null && uri.contains(ExternalBlobAdapter.PREFIX_SEPARATOR)) { 110 String prefix = uri.substring(0, uri.indexOf(ExternalBlobAdapter.PREFIX_SEPARATOR)); 111 return getExternalBlobAdapterForPrefix(prefix); 112 } 113 return null; 114 } 115 116 @Override 117 public Blob getExternalBlobForUri(String uri) throws PropertyException, IOException { 118 ExternalBlobAdapter adapter = getExternalBlobAdapterForUri(uri); 119 if (adapter == null) { 120 throw new PropertyException(String.format("No external blob adapter found for uri '%s'", uri)); 121 } 122 return adapter.getBlob(uri); 123 } 124 125 @Override 126 public BlobHolder getBlobHolderAdapter(DocumentModel doc) { 127 if (factories.containsKey(doc.getType())) { 128 BlobHolderFactory factory = factories.get(doc.getType()); 129 return factory.getBlobHolder(doc); 130 } 131 132 for (Map.Entry<String, BlobHolderFactory> entry : factoriesByFacets.entrySet()) { 133 if (doc.hasFacet(entry.getKey())) { 134 return entry.getValue().getBlobHolder(doc); 135 } 136 } 137 138 if (doc.hasSchema("file")) { 139 return new DocumentBlobHolder(doc, "file:content"); 140 } else if (doc.hasSchema("note")) { 141 String mt = null; 142 try { 143 mt = (String) doc.getPropertyValue("note:mime_type"); 144 if (mt == null) { 145 String note = (String) doc.getPropertyValue("note:note"); 146 if (note != null && !"".equals(note)) { 147 mt = "text/plain"; // BBB 148 } 149 } 150 } catch (PropertyException e) { 151 // mt = null; 152 } 153 return new DocumentStringBlobHolder(doc, "note:note", mt); 154 } 155 return null; 156 } 157 158}