This is an automated email from the ASF dual-hosted git repository. ningjiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git
commit a5e7a16fb33405099756c523b5305a30ee120ba9 Author: wujimin <[email protected]> AuthorDate: Sat Dec 23 16:44:55 2017 +0800 JAV-591 create new mechanism for ResponseMapper --- .../invocation/response/ResponseMapperFactory.java | 36 ++-------- .../response/ResponseMapperFactorys.java | 64 +++++++++++++++++ .../response/TestResponseMapperFactorys.java | 83 ++++++++++++++++++++++ 3 files changed, 154 insertions(+), 29 deletions(-) diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/io/servicecomb/swagger/invocation/response/ResponseMapperFactory.java b/swagger/swagger-invocation/invocation-core/src/main/java/io/servicecomb/swagger/invocation/response/ResponseMapperFactory.java index c737f97..5faf2b5 100644 --- a/swagger/swagger-invocation/invocation-core/src/main/java/io/servicecomb/swagger/invocation/response/ResponseMapperFactory.java +++ b/swagger/swagger-invocation/invocation-core/src/main/java/io/servicecomb/swagger/invocation/response/ResponseMapperFactory.java @@ -16,42 +16,20 @@ */ package io.servicecomb.swagger.invocation.response; -import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.Map; -import javax.inject.Inject; - -import io.servicecomb.swagger.invocation.converter.Converter; import io.servicecomb.swagger.invocation.converter.ConverterMgr; -public abstract class ResponseMapperFactory<MAPPER> { - @Inject - protected ConverterMgr converterMgr; - - // 特殊的应答,比如ResponseEntity/cse Response之类 - protected Map<Class<?>, MAPPER> mappers = new HashMap<>(); - - public void setConverterMgr(ConverterMgr converterMgr) { - this.converterMgr = converterMgr; +public interface ResponseMapperFactory<MAPPER> { + default int getOrder() { + return 0; } - public MAPPER createResponseMapper(Type src, Type target) { - Type type = choose(src, target); - if (ParameterizedType.class.isAssignableFrom(type.getClass())) { - type = ((ParameterizedType) type).getRawType(); - } - MAPPER mapper = mappers.get(type); - if (mapper != null) { - return mapper; - } - - Converter converter = converterMgr.findConverter(src, target); - return doCreateResponseMapper(converter); + default void setConverterMgr(ConverterMgr converterMgr) { } - protected abstract Type choose(Type src, Type target); + boolean isMatch(Type swaggerType, Type providerType); - protected abstract MAPPER doCreateResponseMapper(Converter converter); + MAPPER createResponseMapper(ResponseMapperFactorys<MAPPER> factorys, Type swaggerType, + Type providerType); } diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/io/servicecomb/swagger/invocation/response/ResponseMapperFactorys.java b/swagger/swagger-invocation/invocation-core/src/main/java/io/servicecomb/swagger/invocation/response/ResponseMapperFactorys.java new file mode 100644 index 0000000..1d5e400 --- /dev/null +++ b/swagger/swagger-invocation/invocation-core/src/main/java/io/servicecomb/swagger/invocation/response/ResponseMapperFactorys.java @@ -0,0 +1,64 @@ +/* + * 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 io.servicecomb.swagger.invocation.response; + +import java.lang.reflect.Type; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.servicecomb.foundation.common.utils.SPIServiceUtils; +import io.servicecomb.swagger.invocation.converter.ConverterMgr; + +public class ResponseMapperFactorys<MAPPER> { + private static final Logger LOGGER = LoggerFactory.getLogger(ResponseMapperFactorys.class); + + private List<ResponseMapperFactory<MAPPER>> factorys; + + public ResponseMapperFactorys(Class<? extends ResponseMapperFactory<MAPPER>> factoryCls, ConverterMgr converterMgr) { + this(factoryCls); + this.setConverterMgr(converterMgr); + } + + @SuppressWarnings("unchecked") + public ResponseMapperFactorys(Class<? extends ResponseMapperFactory<MAPPER>> factoryCls) { + factorys = (List<ResponseMapperFactory<MAPPER>>) SPIServiceUtils.getSortedService(factoryCls); + factorys.forEach(factory -> { + LOGGER.info("found factory {} of {}:", factory.getClass().getName(), factoryCls.getName()); + }); + } + + public void setConverterMgr(ConverterMgr converterMgr) { + factorys.forEach(factory -> factory.setConverterMgr(converterMgr)); + } + + public MAPPER createResponseMapper(Type swaggerType, Type providerType) { + for (ResponseMapperFactory<MAPPER> factory : factorys) { + if (!factory.isMatch(swaggerType, providerType)) { + continue; + } + + return factory.createResponseMapper(this, swaggerType, providerType); + } + + throw new IllegalStateException( + String.format("can not find response mapper for %s and %s, this should never happened.", + swaggerType.getTypeName(), + providerType.getTypeName())); + } +} diff --git a/swagger/swagger-invocation/invocation-core/src/test/java/io/servicecomb/swagger/invocation/response/TestResponseMapperFactorys.java b/swagger/swagger-invocation/invocation-core/src/test/java/io/servicecomb/swagger/invocation/response/TestResponseMapperFactorys.java new file mode 100644 index 0000000..bb0173f --- /dev/null +++ b/swagger/swagger-invocation/invocation-core/src/test/java/io/servicecomb/swagger/invocation/response/TestResponseMapperFactorys.java @@ -0,0 +1,83 @@ +/* + * 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 io.servicecomb.swagger.invocation.response; + +import java.util.List; + +import org.hamcrest.Matchers; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import io.servicecomb.swagger.invocation.Response; +import io.servicecomb.swagger.invocation.converter.Converter; +import io.servicecomb.swagger.invocation.converter.ConverterMgr; +import io.servicecomb.swagger.invocation.converter.impl.ConverterSame; +import io.servicecomb.swagger.invocation.response.consumer.CompletableFutureConsumerResponseMapperFactory; +import io.servicecomb.swagger.invocation.response.consumer.ConsumerResponseMapper; +import io.servicecomb.swagger.invocation.response.consumer.ConsumerResponseMapperFactory; +import io.servicecomb.swagger.invocation.response.consumer.CseResponseConsumerResponseMapperFactory; +import io.servicecomb.swagger.invocation.response.consumer.DefaultConsumerResponseMapper; +import io.servicecomb.swagger.invocation.response.consumer.DefaultConsumerResponseMapperFactory; +import mockit.Deencapsulation; + +public class TestResponseMapperFactorys { + ResponseMapperFactorys<ConsumerResponseMapper> consumerResponseMapperFactorys = + new ResponseMapperFactorys<>(ConsumerResponseMapperFactory.class); + + List<ResponseMapperFactory<ConsumerResponseMapper>> factorys = + Deencapsulation.getField(consumerResponseMapperFactorys, "factorys"); + + ConverterMgr converterMgr = new ConverterMgr(); + + @Before + public void setup() { + consumerResponseMapperFactorys.setConverterMgr(converterMgr); + } + + @SuppressWarnings("unchecked") + @Test + public void construct() { + Assert.assertThat(factorys, + Matchers.contains(Matchers.instanceOf(CseResponseConsumerResponseMapperFactory.class), + Matchers.instanceOf(CompletableFutureConsumerResponseMapperFactory.class), + Matchers.instanceOf(DefaultConsumerResponseMapperFactory.class))); + } + + @Test + public void setConverterMgr() { + Assert.assertSame(converterMgr, Deencapsulation.getField(factorys.get(2), "converterMgr")); + } + + @Test + public void createResponseMapper_default() { + ConsumerResponseMapper mapper = consumerResponseMapperFactorys.createResponseMapper(String.class, String.class); + Assert.assertThat(mapper, Matchers.instanceOf(DefaultConsumerResponseMapper.class)); + + Converter converter = Deencapsulation.getField(mapper, "converter"); + Assert.assertSame(ConverterSame.getInstance(), converter); + } + + @Test + public void createResponseMapper_cseResponse() { + ConsumerResponseMapper mapper = consumerResponseMapperFactorys.createResponseMapper(String.class, Response.class); + + Response response = Response.ok(null); + Object result = mapper.mapResponse(response); + Assert.assertSame(response, result); + } +} -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
