001/* 002 * (C) Copyright 2006-2011 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 * 019 */ 020package org.nuxeo.ecm.core.api.blobholder; 021 022import java.io.IOException; 023import java.util.HashMap; 024import java.util.Map; 025import java.util.Set; 026 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<String, BlobHolderFactory>(); 055 056 protected Map<String, BlobHolderFactory> factoriesByFacets = new HashMap<String, BlobHolderFactory>(); 057 058 protected static final Map<String, ExternalBlobAdapter> externalBlobAdapters = new HashMap<String, ExternalBlobAdapter>(); 059 060 @Override 061 public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 062 063 if (BLOBHOLDERFACTORY_EP.equals(extensionPoint)) { 064 BlobHolderFactoryDescriptor desc = (BlobHolderFactoryDescriptor) contribution; 065 String docType = desc.getDocType(); 066 if (docType != null) { 067 factories.put(docType, desc.getFactory()); 068 } 069 String facet = desc.getFacet(); 070 if (facet != null) { 071 factoriesByFacets.put(facet, desc.getFactory()); 072 } 073 } else if (EXTERNALBLOB_ADAPTER_EP.equals(extensionPoint)) { 074 ExternalBlobAdapterDescriptor desc = (ExternalBlobAdapterDescriptor) contribution; 075 ExternalBlobAdapter adapter = desc.getAdapter(); 076 String prefix = desc.getPrefix(); 077 if (externalBlobAdapters.containsKey(prefix)) { 078 log.info(String.format("Overriding external blob adapter with prefix '%s'", prefix)); 079 externalBlobAdapters.remove(prefix); 080 } 081 adapter.setPrefix(desc.getPrefix()); 082 adapter.setProperties(desc.getProperties()); 083 externalBlobAdapters.put(desc.getPrefix(), adapter); 084 log.info(String.format("Registered external blob adapter with prefix '%s'", prefix)); 085 } else { 086 log.error("Unknown extension point " + extensionPoint); 087 } 088 } 089 090 @Override 091 public void unregisterContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 092 } 093 094 /* for test */ 095 096 public static Set<String> getFactoryNames() { 097 return ((BlobHolderAdapterComponent) Framework.getLocalService(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", "file:filename"); 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}