blob: c5d8693b3682691e3f94b4ff689ab6deb9327cfa [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.servicecomb.common.rest.codec.produce;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ws.rs.core.MediaType;
import org.apache.servicecomb.foundation.common.RegisterManager;
import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
public final class ProduceProcessorManager extends RegisterManager<String, Map<String, ProduceProcessor>> {
private static final Logger LOGGER = LoggerFactory.getLogger(ProduceProcessorManager.class);
private static final List<ProduceProcessor> produceProcessor =
SPIServiceUtils.getSortedService(ProduceProcessor.class);
private static final String NAME = "produce processor mgr";
public static final String DEFAULT_TYPE = MediaType.APPLICATION_JSON;
public static final String DEFAULT_SERIAL_CLASS = "servicecomb_default_class";
public static final ProduceProcessorManager INSTANCE = new ProduceProcessorManager();
private final Map<String, ProduceProcessor> nonSerialViewMap = new HashMap<>();
private final Map<String, ProduceProcessor> jsonProcessorMap;
private final Map<String, ProduceProcessor> plainProcessorMap;
private final Map<String, ProduceProcessor> defaultProcessorMap;
private ProduceProcessorManager() {
super(NAME);
produceProcessor.forEach(processor -> {
nonSerialViewMap.put(processor.getName(), processor);
Map<String, ProduceProcessor> prodProcessorMap = getObjMap()
.computeIfAbsent(processor.getName(), key -> new HashMap<>());
prodProcessorMap.putIfAbsent(processor.getSerializationView(), processor);
});
jsonProcessorMap = ensureFindValue(MediaType.APPLICATION_JSON);
plainProcessorMap = ensureFindValue(MediaType.TEXT_PLAIN);
defaultProcessorMap = jsonProcessorMap;
}
private static ProduceProcessor cloneNewProduceProcessor(Class<?> serialViewClass,
Map<String, ProduceProcessor> produceViewMap) {
ProduceProcessor newInstance;
try {
newInstance = produceViewMap.get(DEFAULT_SERIAL_CLASS).getClass().getDeclaredConstructor().newInstance();
newInstance.setSerializationView(serialViewClass);
return newInstance;
} catch (Throwable e) {
// ignore exception
LOGGER.warn("Failed to create produceProcessor with {}", serialViewClass.getName(), e);
}
return produceViewMap.get(DEFAULT_SERIAL_CLASS);
}
// key -> accept type
public Map<String, ProduceProcessor> getOrCreateAcceptMap(Class<?> serialViewClass) {
if (serialViewClass == null) {
return nonSerialViewMap;
}
Map<String, ProduceProcessor> result = new HashMap<>();
getObjMap().forEach((acceptKey, viewMap) -> {
ProduceProcessor produceProcessor = viewMap.computeIfAbsent(serialViewClass.getName(),
viewKey -> cloneNewProduceProcessor(serialViewClass, viewMap));
result.put(acceptKey, produceProcessor);
});
return result;
}
public ProduceProcessor findProcessor(String acceptType, Class<?> serialViewClass) {
Map<String, ProduceProcessor> viewMap = findValue(acceptType);
if (CollectionUtils.isEmpty(viewMap)) {
return null;
}
if (serialViewClass == null) {
return viewMap.get(DEFAULT_SERIAL_CLASS);
}
return viewMap.computeIfAbsent(serialViewClass.getName(),
viewKey -> cloneNewProduceProcessor(serialViewClass, viewMap));
}
public ProduceProcessor findJsonProcessorByViewClass(Class<?> serialViewClass) {
if (serialViewClass == null) {
return jsonProcessorMap.get(DEFAULT_SERIAL_CLASS);
}
return jsonProcessorMap.computeIfAbsent(serialViewClass.getName(),
viewKey -> cloneNewProduceProcessor(serialViewClass, jsonProcessorMap));
}
public ProduceProcessor findDefaultProcessorByViewClass(Class<?> serialViewClass) {
if (serialViewClass == null) {
return defaultProcessorMap.get(DEFAULT_SERIAL_CLASS);
}
return defaultProcessorMap.computeIfAbsent(serialViewClass.getName(),
viewKey -> cloneNewProduceProcessor(serialViewClass, defaultProcessorMap));
}
public ProduceProcessor findPlainProcessorByViewClass(Class<?> serialViewClass) {
if (serialViewClass == null) {
return plainProcessorMap.get(DEFAULT_SERIAL_CLASS);
}
return plainProcessorMap.computeIfAbsent(serialViewClass.getName(),
viewKey -> cloneNewProduceProcessor(serialViewClass, plainProcessorMap));
}
public ProduceProcessor findDefaultJsonProcessor() {
return jsonProcessorMap.get(DEFAULT_SERIAL_CLASS);
}
public ProduceProcessor findDefaultProcessor() {
return defaultProcessorMap.get(DEFAULT_SERIAL_CLASS);
}
public ProduceProcessor findDefaultPlainProcessor() {
return plainProcessorMap.get(DEFAULT_SERIAL_CLASS);
}
}