blob: 79cbba7a7eb471dd150915b0009880fb5802b948 [file] [log] [blame]
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.qpid.server.message.mimecontentconverter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.qpid.server.plugin.QpidServiceLoader;
public class MimeContentConverterRegistry
{
private static final Logger LOGGER = LoggerFactory.getLogger(MimeContentConverterRegistry.class);
private static final Map<String, MimeContentToObjectConverter> _mimeContentToObjectConverters;
private static final Multimap<Class, ObjectToMimeContentConverter> _classToMimeContentConverters;
static
{
_classToMimeContentConverters = buildClassToMimeConverters();
_mimeContentToObjectConverters = buildMimeContentToObjectMap();
}
private static Multimap<Class, ObjectToMimeContentConverter> buildClassToMimeConverters()
{
Multimap<Class, ObjectToMimeContentConverter> classToMineConverters = HashMultimap.create();
Iterable<ObjectToMimeContentConverter> objectToMimeContentConverters = new QpidServiceLoader().instancesOf(ObjectToMimeContentConverter.class);
for(ObjectToMimeContentConverter converter : objectToMimeContentConverters)
{
Class objectClass = converter.getObjectClass();
for(ObjectToMimeContentConverter existing : classToMineConverters.get(objectClass))
{
if (existing.getRank() == converter.getRank())
{
LOGGER.warn("MIME converter for object class {} has two or more implementations"
+ " with the same rank {}. It is undefined which one will be used."
+ " Implementations are: {} {} ",
existing.getObjectClass().getName(),
existing.getRank(),
existing.getClass().getName(),
converter.getClass().getName());
}
}
classToMineConverters.put(objectClass, converter);
}
classToMineConverters.put(Void.class, new IdentityConverter());
return ImmutableMultimap.copyOf(classToMineConverters);
}
private static Map<String, MimeContentToObjectConverter> buildMimeContentToObjectMap()
{
final Map<String, MimeContentToObjectConverter> mimeContentToObjectConverters = new HashMap<>();
for(MimeContentToObjectConverter converter : (new QpidServiceLoader()).instancesOf(MimeContentToObjectConverter.class))
{
final String mimeType = converter.getMimeType();
final MimeContentToObjectConverter existing = mimeContentToObjectConverters.put(mimeType, converter);
if (existing != null)
{
LOGGER.warn("MIME converter {} for mime type '{}' replaced by {}.",
existing.getClass().getName(),
existing.getMimeType(),
converter.getClass().getName());
}
}
return Collections.unmodifiableMap(mimeContentToObjectConverters);
}
public static MimeContentToObjectConverter getMimeContentToObjectConverter(String mimeType)
{
return _mimeContentToObjectConverters.get(mimeType);
}
public static ObjectToMimeContentConverter getBestFitObjectToMimeContentConverter(Object object)
{
ObjectToMimeContentConverter converter = null;
if (object != null)
{
final List<Class<?>> classes = new ArrayList<>(Arrays.asList(object.getClass().getInterfaces()));
classes.add(object.getClass());
for (Class<?> i : classes)
{
for (ObjectToMimeContentConverter candidate : _classToMimeContentConverters.get(i))
{
if (candidate.isAcceptable(object))
{
if (converter == null || candidate.getRank() > converter.getRank())
{
converter = candidate;
}
}
}
}
}
return converter;
}
public static ObjectToMimeContentConverter getBestFitObjectToMimeContentConverter(Object object, Class<?> typeHint)
{
ObjectToMimeContentConverter converter = null;
for (ObjectToMimeContentConverter candidate : _classToMimeContentConverters.get(typeHint))
{
if (candidate.isAcceptable(object))
{
if (converter == null || candidate.getRank() > converter.getRank())
{
converter = candidate;
}
}
}
return converter;
}
}