001/* 002 * (C) Copyright 2006-2007 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 */ 017package org.nuxeo.ecm.diff.content.adapter; 018 019import java.util.HashMap; 020import java.util.Map; 021 022import org.apache.commons.lang.StringUtils; 023import org.apache.commons.logging.Log; 024import org.apache.commons.logging.LogFactory; 025import org.nuxeo.ecm.core.api.DocumentModel; 026import org.nuxeo.ecm.core.api.blobholder.BlobHolder; 027import org.nuxeo.ecm.diff.content.ContentDiffAdapter; 028import org.nuxeo.ecm.diff.content.ContentDiffException; 029import org.nuxeo.ecm.diff.content.adapter.factories.BlobHolderContentDiffAdapterFactory; 030import org.nuxeo.ecm.diff.content.adapter.factories.FileBasedContentDiffAdapterFactory; 031import org.nuxeo.runtime.model.ComponentInstance; 032import org.nuxeo.runtime.model.DefaultComponent; 033 034/** 035 * Runtime component that handles the extension points and the service interface for content diff Adapter management. 036 * 037 * @author Antoine Taillefer 038 */ 039public class ContentDiffAdapterManagerComponent extends DefaultComponent implements ContentDiffAdapterManager { 040 041 public static final String ADAPTER_FACTORY_EP = "adapterFactory"; 042 043 public static final String MIME_TYPE_CONTENT_DIFFER_EP = "mimeTypeContentDiffer"; 044 045 private static final Log log = LogFactory.getLog(ContentDiffAdapterManagerComponent.class); 046 047 protected Map<String, ContentDiffAdapterFactory> factoryRegistry = new HashMap<String, ContentDiffAdapterFactory>(); 048 049 protected Map<String, MimeTypeContentDiffer> contentDifferFactory = new HashMap<String, MimeTypeContentDiffer>(); 050 051 protected Map<String, MimeTypeContentDiffer> contentDifferFactoryByName = new HashMap<String, MimeTypeContentDiffer>(); 052 053 // Component and EP management 054 055 @Override 056 public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 057 058 if (ADAPTER_FACTORY_EP.equals(extensionPoint)) { 059 ContentDiffAdapterFactoryDescriptor desc = (ContentDiffAdapterFactoryDescriptor) contribution; 060 if (desc.isEnabled()) { 061 ContentDiffAdapterFactory factory = desc.getNewInstance(); 062 if (factory != null) { 063 factoryRegistry.put(desc.getTypeName(), factory); 064 } 065 } else { 066 factoryRegistry.remove(desc.getTypeName()); 067 } 068 } else if (MIME_TYPE_CONTENT_DIFFER_EP.equals(extensionPoint)) { 069 MimeTypeContentDifferDescriptor desc = (MimeTypeContentDifferDescriptor) contribution; 070 try { 071 MimeTypeContentDiffer contentDiffer = desc.getKlass().newInstance(); 072 contentDifferFactory.put(desc.getPattern(), contentDiffer); 073 074 // Also (since 7.4) add a name in the contribution 075 String name = desc.getName(); 076 if (StringUtils.isNotBlank(name)) { 077 contentDifferFactoryByName.put(name, contentDiffer); 078 } 079 } catch (ReflectiveOperationException e) { 080 throw new RuntimeException(e); 081 } 082 } 083 } 084 085 @Override 086 public void unregisterContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 087 } 088 089 // Service interface impl 090 091 @Override 092 public boolean hasAdapter(DocumentModel doc) { 093 if (doc == null) { 094 return false; 095 } 096 097 String docType = doc.getType(); 098 if (factoryRegistry.containsKey(docType)) { 099 return true; 100 } 101 102 return doc.hasSchema("file") || doc.hasSchema("files"); 103 } 104 105 @Override 106 public ContentDiffAdapter getAdapter(DocumentModel doc) { 107 if (doc == null) { 108 return null; 109 } 110 111 String docType = doc.getType(); 112 113 log.debug("Looking for ContentDiffAdapter for type " + docType); 114 115 if (factoryRegistry.containsKey(docType)) { 116 log.debug("Dedicated ContentDiffAdapter factory found"); 117 return factoryRegistry.get(docType).getAdapter(doc); 118 } 119 120 if (doc.isFolder()) { 121 return null; 122 } 123 124 BlobHolder bh = doc.getAdapter(BlobHolder.class); 125 if (bh != null) { 126 log.debug("Using Blob Holder based ContentDiffAdapter factory"); 127 ContentDiffAdapterFactory factory = new BlobHolderContentDiffAdapterFactory(); 128 return factory.getAdapter(doc); 129 130 } 131 132 if (doc.hasSchema("file") || doc.hasSchema("files")) { 133 log.debug("Using default file based ContentDiffAdapter factory"); 134 ContentDiffAdapterFactory factory = new FileBasedContentDiffAdapterFactory(); 135 return factory.getAdapter(doc); 136 } else { 137 return null; 138 } 139 } 140 141 @Override 142 public MimeTypeContentDiffer getContentDiffer(String mimeType) { 143 for (Map.Entry<String, MimeTypeContentDiffer> entry : contentDifferFactory.entrySet()) { 144 if (mimeType.matches(entry.getKey())) { 145 return entry.getValue(); 146 } 147 } 148 return null; 149 } 150 151 @Override 152 public MimeTypeContentDiffer getContentDifferForName(String name) { 153 for (Map.Entry<String, MimeTypeContentDiffer> entry : contentDifferFactoryByName.entrySet()) { 154 if (name.equals(entry.getKey())) { 155 return entry.getValue(); 156 } 157 } 158 return null; 159 } 160 161 @Override 162 public HtmlContentDiffer getHtmlContentDiffer() throws ContentDiffException { 163 MimeTypeContentDiffer htmlContentDiffer = contentDifferFactory.get("text/html"); 164 if (htmlContentDiffer == null || !(htmlContentDiffer instanceof HtmlContentDiffer)) { 165 throw new ContentDiffException( 166 "No content differ of type HtmlContentDiffer found for the 'text/html' mime-type. Please check the 'mimeTypeContentDiffer' contributions."); 167 } 168 return (HtmlContentDiffer) htmlContentDiffer; 169 } 170 171}