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 * $Id$ 020 */ 021 022package org.nuxeo.ecm.core.convert.extension; 023 024import java.io.Serializable; 025import java.util.ArrayList; 026import java.util.List; 027import java.util.Map; 028 029import org.nuxeo.ecm.core.api.blobholder.BlobHolder; 030import org.nuxeo.ecm.core.convert.api.ConversionException; 031import org.nuxeo.ecm.core.convert.service.ConversionServiceImpl; 032import org.nuxeo.ecm.core.convert.service.MimeTypeTranslationHelper; 033import org.nuxeo.runtime.api.Framework; 034 035/** 036 * Specific {@link Converter} implementation that acts as a converters chain. 037 * <p> 038 * The chain can be: 039 * <ul> 040 * <li>a chain of mime-types 041 * <li>a chain of converter names 042 * </ul> 043 * <p> 044 * This depends on the properties of the descriptor. 045 * 046 * @author tiry 047 */ 048public class ChainedConverter implements Converter { 049 050 protected boolean subConvertersBased = false; 051 052 protected List<String> steps = new ArrayList<String>(); 053 054 protected List<String> subConverters = new ArrayList<String>(); 055 056 public ChainedConverter() { 057 subConvertersBased = false; 058 subConverters = null; 059 } 060 061 public ChainedConverter(List<String> subConverters) { 062 subConvertersBased = true; 063 this.subConverters = subConverters; 064 steps = null; 065 } 066 067 @Override 068 public BlobHolder convert(BlobHolder blobHolder, Map<String, Serializable> parameters) throws ConversionException { 069 070 if (subConvertersBased) { 071 return convertBasedSubConverters(blobHolder, parameters); 072 } else { 073 return convertBasedOnMimeTypes(blobHolder, parameters); 074 } 075 } 076 077 protected BlobHolder convertBasedSubConverters(BlobHolder blobHolder, Map<String, Serializable> parameters) 078 throws ConversionException { 079 String srcMT = blobHolder.getBlob().getMimeType(); 080 BlobHolder result = blobHolder; 081 for (String converterName : subConverters) { 082 ConverterDescriptor desc = ConversionServiceImpl.getConverterDescriptor(converterName); 083 if (!desc.getSourceMimeTypes().contains(srcMT)) { 084 throw new ConversionException("Conversion Chain is not well defined"); 085 } 086 Converter converter = ConversionServiceImpl.getConverter(converterName); 087 result = converter.convert(result, parameters); 088 srcMT = desc.getDestinationMimeType(); 089 } 090 return result; 091 } 092 093 /** 094 * Tries to find a chain of converters that fits the mime-types chain. 095 */ 096 protected BlobHolder convertBasedOnMimeTypes(BlobHolder blobHolder, Map<String, Serializable> parameters) 097 throws ConversionException { 098 String srcMT = blobHolder.getBlob().getMimeType(); 099 BlobHolder result = blobHolder; 100 for (String dstMT : steps) { 101 String converterName = Framework.getService(MimeTypeTranslationHelper.class).getConverterName(srcMT, dstMT); 102 if (converterName == null) { 103 throw new ConversionException( 104 "Chained conversion error : unable to find converter between " + srcMT + " and " + dstMT); 105 } 106 Converter converter = ConversionServiceImpl.getConverter(converterName); 107 result = converter.convert(result, parameters); 108 srcMT = dstMT; 109 } 110 return result; 111 } 112 113 @Override 114 public void init(ConverterDescriptor descriptor) { 115 if (!subConvertersBased) { 116 steps.addAll(descriptor.getSteps()); 117 steps.add(descriptor.getDestinationMimeType()); 118 } else { 119 ConverterDescriptor fconv = ConversionServiceImpl.getConverterDescriptor(subConverters.get(0)); 120 ConverterDescriptor lconv = ConversionServiceImpl.getConverterDescriptor(subConverters.get(subConverters.size() - 1)); 121 122 descriptor.sourceMimeTypes = fconv.sourceMimeTypes; 123 descriptor.destinationMimeType = lconv.destinationMimeType; 124 } 125 } 126 127 public List<String> getSteps() { 128 return steps; 129 } 130 131 /** 132 * Returns the sub converters of this chained converter. 133 * 134 * @since 5.9.2 135 */ 136 public List<String> getSubConverters() { 137 return subConverters; 138 } 139 140 /** 141 * Returns true if this chained converter is sub converters based, false otherwise. 142 * 143 * @since 5.9.4 144 */ 145 public boolean isSubConvertersBased() { 146 return subConvertersBased; 147 } 148}