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.lang3.StringUtils; 027import org.apache.commons.logging.Log; 028import org.apache.commons.logging.LogFactory; 029import org.nuxeo.ecm.core.api.Blob; 030import org.nuxeo.ecm.core.api.DocumentModel; 031import org.nuxeo.ecm.core.api.PropertyException; 032import org.nuxeo.ecm.core.api.adapter.DocumentAdapterFactory; 033import org.nuxeo.ecm.core.api.externalblob.ExternalBlobAdapter; 034import org.nuxeo.ecm.core.api.externalblob.ExternalBlobAdapterDescriptor; 035import org.nuxeo.runtime.api.Framework; 036import org.nuxeo.runtime.model.ComponentInstance; 037import org.nuxeo.runtime.model.DefaultComponent; 038 039/** 040 * Runtime component to manage the pluggable factory for {@link DocumentAdapterFactory}. 041 * <p> 042 * Also provides the service interface {@link BlobHolderAdapterService} 043 * 044 * @author tiry 045 */ 046public class BlobHolderAdapterComponent extends DefaultComponent implements BlobHolderAdapterService { 047 048 private static final Log log = LogFactory.getLog(BlobHolderAdapterComponent.class); 049 050 public static final String BLOBHOLDERFACTORY_EP = "BlobHolderFactory"; 051 052 public static final String EXTERNALBLOB_ADAPTER_EP = "ExternalBlobAdapter"; 053 054 protected final Map<String, BlobHolderFactory> factories = new HashMap<>(); 055 056 protected Map<String, BlobHolderFactory> factoriesByFacets = new HashMap<>(); 057 058 protected Map<String, BlobHolderFactory> factoriesByName = new HashMap<>(); 059 060 protected static final Map<String, ExternalBlobAdapter> externalBlobAdapters = new HashMap<>(); 061 062 @Override 063 public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 064 065 if (BLOBHOLDERFACTORY_EP.equals(extensionPoint)) { 066 BlobHolderFactoryDescriptor desc = (BlobHolderFactoryDescriptor) contribution; 067 String name = desc.getName(); 068 if (StringUtils.isNotBlank(name)) { 069 factoriesByName.put(name, desc.getFactory()); 070 } 071 String docType = desc.getDocType(); 072 if (docType != null) { 073 factories.put(docType, desc.getFactory()); 074 } 075 String facet = desc.getFacet(); 076 if (facet != null) { 077 factoriesByFacets.put(facet, desc.getFactory()); 078 } 079 } else if (EXTERNALBLOB_ADAPTER_EP.equals(extensionPoint)) { 080 ExternalBlobAdapterDescriptor desc = (ExternalBlobAdapterDescriptor) contribution; 081 ExternalBlobAdapter adapter = desc.getAdapter(); 082 String prefix = desc.getPrefix(); 083 if (externalBlobAdapters.containsKey(prefix)) { 084 log.info(String.format("Overriding external blob adapter with prefix '%s'", prefix)); 085 externalBlobAdapters.remove(prefix); 086 } 087 adapter.setPrefix(desc.getPrefix()); 088 adapter.setProperties(desc.getProperties()); 089 externalBlobAdapters.put(desc.getPrefix(), adapter); 090 log.info(String.format("Registered external blob adapter with prefix '%s'", prefix)); 091 } else { 092 log.error("Unknown extension point " + extensionPoint); 093 } 094 } 095 096 @Override 097 public void unregisterContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 098 } 099 100 /* for test */ 101 102 public static Set<String> getFactoryNames() { 103 return ((BlobHolderAdapterComponent) Framework.getService( 104 BlobHolderAdapterService.class)).factories.keySet(); 105 } 106 107 /* Service Interface */ 108 109 @Override 110 public ExternalBlobAdapter getExternalBlobAdapterForPrefix(String prefix) { 111 return externalBlobAdapters.get(prefix); 112 } 113 114 @Override 115 public ExternalBlobAdapter getExternalBlobAdapterForUri(String uri) { 116 if (uri != null && uri.contains(ExternalBlobAdapter.PREFIX_SEPARATOR)) { 117 String prefix = uri.substring(0, uri.indexOf(ExternalBlobAdapter.PREFIX_SEPARATOR)); 118 return getExternalBlobAdapterForPrefix(prefix); 119 } 120 return null; 121 } 122 123 @Override 124 public Blob getExternalBlobForUri(String uri) throws PropertyException, IOException { 125 ExternalBlobAdapter adapter = getExternalBlobAdapterForUri(uri); 126 if (adapter == null) { 127 throw new PropertyException(String.format("No external blob adapter found for uri '%s'", uri)); 128 } 129 return adapter.getBlob(uri); 130 } 131 132 @Override 133 public BlobHolder getBlobHolderAdapter(DocumentModel doc, String factoryName) { 134 if (factoryName != null && factoriesByName.containsKey(factoryName)) { 135 BlobHolderFactory factory = factoriesByName.get(factoryName); 136 return factory.getBlobHolder(doc); 137 } 138 139 if (factories.containsKey(doc.getType())) { 140 BlobHolderFactory factory = factories.get(doc.getType()); 141 return factory.getBlobHolder(doc); 142 } 143 144 for (Map.Entry<String, BlobHolderFactory> entry : factoriesByFacets.entrySet()) { 145 if (doc.hasFacet(entry.getKey())) { 146 return entry.getValue().getBlobHolder(doc); 147 } 148 } 149 150 if (doc.hasSchema("file")) { 151 return new DocumentBlobHolder(doc, "file:content"); 152 } else if (doc.hasSchema("note")) { 153 String mt = null; 154 try { 155 mt = (String) doc.getPropertyValue("note:mime_type"); 156 if (mt == null) { 157 String note = (String) doc.getPropertyValue("note:note"); 158 if (note != null && !"".equals(note)) { 159 mt = "text/plain"; // BBB 160 } 161 } 162 } catch (PropertyException e) { 163 // mt = null; 164 } 165 return new DocumentStringBlobHolder(doc, "note:note", mt); 166 } 167 return null; 168 } 169 170 @Override 171 public BlobHolder getBlobHolderAdapter(DocumentModel doc) { 172 return getBlobHolderAdapter(doc, null); 173 } 174 175}