You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2019/01/16 10:00:17 UTC

[servicecomb-java-chassis] 04/04: [SCB-1046] file upload support file array for the same name:fix as reviewed

This is an automated email from the ASF dual-hosted git repository.

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git

commit 1252f9c12f8d5219dac921b04495ae66974c5ef1
Author: heyile <25...@qq.com>
AuthorDate: Mon Jan 14 11:41:00 2019 +0800

    [SCB-1046] file upload support file array for the same name:fix as reviewed
---
 .../rest/codec/param/FormProcessorCreator.java     | 13 ++--
 .../rest/codec/param/RestClientRequestImpl.java    | 71 +++++++---------------
 .../common/rest/definition/RestOperationMeta.java  | 10 +++
 .../codec/param/TestRestClientRequestImpl.java     |  9 ++-
 .../VertxServerRequestToHttpServletRequest.java    |  6 +-
 .../reference/CommonToHttpServletRequest.java      | 24 +++-----
 .../springmvc/reference/CseClientHttpRequest.java  |  2 +-
 .../reference/TestCommonToHttpServletRequest.java  | 49 +++------------
 .../swagger/generator/core/OperationGenerator.java |  2 +-
 .../swagger/invocation/converter/ConverterMgr.java |  2 +-
 10 files changed, 65 insertions(+), 123 deletions(-)

diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/FormProcessorCreator.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/FormProcessorCreator.java
index 48de6ad..6980e94 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/FormProcessorCreator.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/FormProcessorCreator.java
@@ -18,7 +18,6 @@
 package org.apache.servicecomb.common.rest.codec.param;
 
 import java.lang.reflect.Type;
-import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -29,7 +28,6 @@ import javax.ws.rs.core.Response.Status;
 
 import org.apache.servicecomb.common.rest.RestConst;
 import org.apache.servicecomb.common.rest.codec.RestClientRequest;
-import org.apache.servicecomb.foundation.vertx.http.FileUploadPart;
 import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
 
 import com.fasterxml.jackson.databind.JavaType;
@@ -41,6 +39,7 @@ import io.swagger.models.properties.FileProperty;
 import io.swagger.models.properties.Property;
 
 public class FormProcessorCreator implements ParamValueProcessorCreator {
+
   public static final String PARAMTYPE = "formData";
 
   public static class FormProcessor extends AbstractParamProcessor {
@@ -108,9 +107,7 @@ public class FormProcessorCreator implements ParamValueProcessorCreator {
     FormParameter formParameter = (FormParameter) parameter;
     if ("array".equals(formParameter.getType())) {
       Property items = formParameter.getItems();
-      if (items != null) {
-        return new FileProperty().getType().equals(items.getType());
-      }
+      return new FileProperty().getType().equals(items.getType());
     }
     return new FileProperty().getType().equals(formParameter.getType());
   }
@@ -126,10 +123,10 @@ public class FormProcessorCreator implements ParamValueProcessorCreator {
         JavaType contentType = targetType.getContentType();
         if (contentType != null && contentType.getRawClass().equals(Part.class)) {
           //get all parts
-          Collection<Part> parts = request.getParts();
-          List<Part> collect = parts.stream().filter(part -> part.getName().equals(paramPath))
+          return request.getParts()
+              .stream()
+              .filter(part -> part.getName().equals(paramPath))
               .collect(Collectors.toList());
-          return collect;
         }
       }
       return request.getPart(paramPath);
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/RestClientRequestImpl.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/RestClientRequestImpl.java
index fbf56f2..2bb92a9 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/RestClientRequestImpl.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/RestClientRequestImpl.java
@@ -22,7 +22,6 @@ import static javax.ws.rs.core.MediaType.MULTIPART_FORM_DATA;
 
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -41,6 +40,9 @@ import org.apache.servicecomb.swagger.invocation.AsyncResponse;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+
 import io.vertx.core.Context;
 import io.vertx.core.MultiMap;
 import io.vertx.core.buffer.Buffer;
@@ -54,8 +56,7 @@ public class RestClientRequestImpl implements RestClientRequest {
 
   protected AsyncResponse asyncResp;
 
-  // maybe part or list of parts
-  private final Map<String, Object> uploads = new HashMap<>();
+  private final Multimap<String, Part> uploads = ArrayListMultimap.create();
 
   protected HttpClientRequest request;
 
@@ -83,12 +84,19 @@ public class RestClientRequestImpl implements RestClientRequest {
   }
 
   @Override
+  @SuppressWarnings("unchecked")
   public void attach(String name, Object part) {
     if (null == part) {
       LOGGER.debug("null file is ignored, file name = [{}]", name);
       return;
     }
-    uploads.put(name, part);
+    if (List.class.isAssignableFrom(part.getClass())) {
+      List<Part> parts = (List<Part>) part;
+      uploads.putAll(name, parts);
+      return;
+    }
+    // must be part
+    uploads.put(name, (Part) part);
   }
 
   @Override
@@ -158,48 +166,34 @@ public class RestClientRequestImpl implements RestClientRequest {
   }
 
   private void attachFiles(String boundary) {
-    Iterator<Entry<String, Object>> uploadsIterator = uploads.entrySet().iterator();
-    List<NamePartMap> namePartMaps = new ArrayList<>();
-    while (uploadsIterator.hasNext()) {
-      Entry<String, Object> entry = uploadsIterator.next();
-      String name = entry.getKey();
-      Object tmpPart = entry.getValue();
-      if (tmpPart instanceof Part) {
-        namePartMaps.add(new NamePartMap(name, (Part) tmpPart));
-      } else {
-        //it's a list
-        @SuppressWarnings("unchecked")
-        List<Part> partList = (List<Part>) tmpPart;
-        partList.forEach(part -> namePartMaps.add(new NamePartMap(name, part)));
-      }
-    }
-    attachFile(boundary, namePartMaps.iterator());
+    Iterator<Entry<String, Part>> uploadsIterator = uploads.entries().iterator();
+    attachFile(boundary, uploadsIterator);
   }
 
-  private void attachFile(String boundary, Iterator<NamePartMap> uploadsIterator) {
+  private void attachFile(String boundary, Iterator<Entry<String, Part>> uploadsIterator) {
     if (!uploadsIterator.hasNext()) {
       request.write(boundaryEndInfo(boundary));
       request.end();
       return;
     }
 
-    NamePartMap next = uploadsIterator.next();
+    Entry<String, Part> entry = uploadsIterator.next();
     // do not use part.getName() to get parameter name
     // because pojo consumer not easy to set name to part
-
-    String filename = next.getPart().getSubmittedFileName();
-
-    Buffer fileHeader = fileBoundaryInfo(boundary, next.getName(), next.getPart());
+    String name = entry.getKey();
+    Part part = entry.getValue();
+    String filename = part.getSubmittedFileName();
+    Buffer fileHeader = fileBoundaryInfo(boundary, name, part);
     request.write(fileHeader);
 
-    new PumpFromPart(context, next.getPart()).toWriteStream(request).whenComplete((v, e) -> {
+    new PumpFromPart(context, part).toWriteStream(request).whenComplete((v, e) -> {
       if (e != null) {
-        LOGGER.debug("Failed to sending file [{}:{}].", next.getName(), filename, e);
+        LOGGER.debug("Failed to sending file [{}:{}].", name, filename, e);
         asyncResp.consumerFail(e);
         return;
       }
 
-      LOGGER.debug("finish sending file [{}:{}].", next.getName(), filename);
+      LOGGER.debug("finish sending file [{}:{}].", name, filename);
       attachFile(boundary, uploadsIterator);
     });
   }
@@ -294,23 +288,4 @@ public class RestClientRequestImpl implements RestClientRequest {
   public MultiMap getHeaders() {
     return request.headers();
   }
-
-  public static class NamePartMap {
-    String name;
-
-    Part part;
-
-    public NamePartMap(String name, Part part) {
-      this.name = name;
-      this.part = part;
-    }
-
-    public String getName() {
-      return name;
-    }
-
-    public Part getPart() {
-      return part;
-    }
-  }
 }
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/RestOperationMeta.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/RestOperationMeta.java
index a417ef2..2c2f2fc 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/RestOperationMeta.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/RestOperationMeta.java
@@ -30,6 +30,7 @@ import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
 
 import org.apache.commons.lang3.StringUtils;
+import org.apache.servicecomb.common.rest.codec.param.FormProcessorCreator.PartProcessor;
 import org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor;
 import org.apache.servicecomb.common.rest.codec.produce.ProduceProcessorManager;
 import org.apache.servicecomb.common.rest.definition.path.PathRegExp;
@@ -64,6 +65,8 @@ public class RestOperationMeta {
   // key为参数名
   protected Map<String, RestParam> paramMap = new LinkedHashMap<>();
 
+  protected List<String> fileKeys = new ArrayList<>();
+
   // key为数据类型,比如json之类
   private Map<String, ProduceProcessor> produceProcessorMap = new LinkedHashMap<>();
 
@@ -219,6 +222,9 @@ public class RestOperationMeta {
   }
 
   private void addParam(RestParam param) {
+    if (param.getParamProcessor() instanceof PartProcessor) {
+      fileKeys.add(param.getParamName());
+    }
     paramList.add(param);
     paramMap.put(param.getParamName(), param);
   }
@@ -258,6 +264,10 @@ public class RestOperationMeta {
     return operationMeta.getHttpMethod();
   }
 
+  public List<String> getFileKeys() {
+    return fileKeys;
+  }
+
   public List<String> getProduces() {
     return produces;
   }
diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestRestClientRequestImpl.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestRestClientRequestImpl.java
index 137063f..6bcb3f9 100644
--- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestRestClientRequestImpl.java
+++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestRestClientRequestImpl.java
@@ -16,6 +16,7 @@
  */
 package org.apache.servicecomb.common.rest.codec.param;
 
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
@@ -28,6 +29,8 @@ import org.junit.Assert;
 import org.junit.Test;
 import org.mockito.Mockito;
 
+import com.google.common.collect.Multimap;
+
 import io.vertx.core.MultiMap;
 import io.vertx.core.buffer.Buffer;
 import io.vertx.core.http.CaseInsensitiveHeaders;
@@ -129,9 +132,9 @@ public class TestRestClientRequestImpl {
 
     restClientRequest.attach(fileName, part);
 
-    Map<String, Part> uploads = Deencapsulation.getField(restClientRequest, "uploads");
+    Multimap<String, Part> uploads = Deencapsulation.getField(restClientRequest, "uploads");
     Assert.assertEquals(1, uploads.size());
-    Assert.assertThat(uploads, Matchers.hasEntry(fileName, part));
+    Assert.assertThat(uploads.asMap(), Matchers.hasEntry(fileName, Arrays.asList(part)));
   }
 
   @Test
@@ -140,7 +143,7 @@ public class TestRestClientRequestImpl {
 
     restClientRequest.attach("fileName", null);
 
-    Map<String, Part> uploads = Deencapsulation.getField(restClientRequest, "uploads");
+    Multimap<String, Part> uploads = Deencapsulation.getField(restClientRequest, "uploads");
     Assert.assertTrue(uploads.isEmpty());
   }
 
diff --git a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/VertxServerRequestToHttpServletRequest.java b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/VertxServerRequestToHttpServletRequest.java
index 6280ef1..d7dfdcc 100644
--- a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/VertxServerRequestToHttpServletRequest.java
+++ b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/VertxServerRequestToHttpServletRequest.java
@@ -17,7 +17,6 @@
 
 package org.apache.servicecomb.foundation.vertx.http;
 
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Enumeration;
@@ -26,6 +25,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import javax.servlet.AsyncContext;
 import javax.servlet.ServletInputStream;
@@ -280,9 +280,7 @@ public class VertxServerRequestToHttpServletRequest extends AbstractHttpServletR
   @Override
   public Collection<Part> getParts() {
     Set<FileUpload> fileUploads = context.fileUploads();
-    List<Part> partList = new ArrayList<>();
-    fileUploads.stream().map(FileUploadPart::new).forEach(partList::add);
-    return partList;
+    return fileUploads.stream().map(FileUploadPart::new).collect(Collectors.toList());
   }
 
   public RoutingContext getContext() {
diff --git a/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CommonToHttpServletRequest.java b/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CommonToHttpServletRequest.java
index 56e3c5a..5bfe5e3 100644
--- a/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CommonToHttpServletRequest.java
+++ b/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CommonToHttpServletRequest.java
@@ -35,8 +35,6 @@ import javax.servlet.http.Part;
 import javax.ws.rs.core.HttpHeaders;
 
 import org.apache.servicecomb.common.rest.RestConst;
-import org.apache.servicecomb.common.rest.codec.param.FormProcessorCreator.PartProcessor;
-import org.apache.servicecomb.common.rest.definition.RestParam;
 import org.apache.servicecomb.foundation.common.part.FilePart;
 import org.apache.servicecomb.foundation.common.part.InputStreamPart;
 import org.apache.servicecomb.foundation.common.part.ResourcePart;
@@ -59,15 +57,9 @@ public class CommonToHttpServletRequest extends AbstractHttpServletRequest {
 
   @SuppressWarnings("unchecked")
   public CommonToHttpServletRequest(Map<String, String> pathParams, Map<String, List<String>> queryParams,
-      Map<String, List<String>> httpHeaders, Object bodyObject, boolean isFormData, List<RestParam> paramList) {
+      Map<String, List<String>> httpHeaders, Object bodyObject, boolean isFormData, List<String> fileKeys) {
     setAttribute(RestConst.PATH_PARAMETERS, pathParams);
-    if (paramList != null && paramList.size() != 0) {
-      for (RestParam param : paramList) {
-        if (param.getParamProcessor() instanceof PartProcessor) {
-          fileKeys.add(param.getParamName());
-        }
-      }
-    }
+    this.fileKeys = fileKeys;
     if (isFormData) {
       setAttribute(RestConst.FORM_PARAMETERS, (Map<String, Object>) bodyObject);
     } else {
@@ -228,7 +220,6 @@ public class CommonToHttpServletRequest extends AbstractHttpServletRequest {
   }
 
   private void filePartListWithForm(List<Part> partList, Map<String, Object> form) {
-
     for (String key : fileKeys) {
       Object value = form.get(key);
       if (value == null) {
@@ -236,20 +227,19 @@ public class CommonToHttpServletRequest extends AbstractHttpServletRequest {
       }
       if (Collection.class.isInstance(value)) {
         Collection<?> collection = (Collection<?>) value;
-        if (collection.isEmpty()) {
-          continue;
-        }
         for (Object part : collection) {
           partList.add(getSinglePart(key, part));
         }
-      } else if (value.getClass().isArray()) {
+        continue;
+      }
+      if (value.getClass().isArray()) {
         Object[] params = (Object[]) value;
         for (int i = 0; i < params.length; i++) {
           partList.add(getSinglePart(key, params[i]));
         }
-      } else {
-        partList.add(getSinglePart(key, value));
+        continue;
       }
+      partList.add(getSinglePart(key, value));
     }
   }
 
diff --git a/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseClientHttpRequest.java b/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseClientHttpRequest.java
index cc6d6d1..1191391 100644
--- a/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseClientHttpRequest.java
+++ b/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseClientHttpRequest.java
@@ -207,7 +207,7 @@ public class CseClientHttpRequest implements ClientHttpRequest {
   protected Object[] collectArguments() {
     HttpServletRequest mockRequest = new CommonToHttpServletRequest(requestMeta.getPathParams(), queryParams,
         httpHeaders, requestBody, requestMeta.getSwaggerRestOperation().isFormData(),
-        requestMeta.getSwaggerRestOperation().getParamList());
+        requestMeta.getSwaggerRestOperation().getFileKeys());
     return RestCodec.restToArgs(mockRequest, requestMeta.getSwaggerRestOperation());
   }
 }
diff --git a/providers/provider-springmvc/src/test/java/org/apache/servicecomb/provider/springmvc/reference/TestCommonToHttpServletRequest.java b/providers/provider-springmvc/src/test/java/org/apache/servicecomb/provider/springmvc/reference/TestCommonToHttpServletRequest.java
index 52d925c..6461e6a 100644
--- a/providers/provider-springmvc/src/test/java/org/apache/servicecomb/provider/springmvc/reference/TestCommonToHttpServletRequest.java
+++ b/providers/provider-springmvc/src/test/java/org/apache/servicecomb/provider/springmvc/reference/TestCommonToHttpServletRequest.java
@@ -33,16 +33,11 @@ import javax.servlet.http.Part;
 import javax.ws.rs.core.HttpHeaders;
 
 import org.apache.servicecomb.common.rest.RestConst;
-import org.apache.servicecomb.common.rest.codec.param.FormProcessorCreator.PartProcessor;
-import org.apache.servicecomb.common.rest.definition.RestParam;
 import org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;
 import org.hamcrest.Matchers;
 import org.junit.Assert;
 import org.junit.Test;
 
-import mockit.Expectations;
-import mockit.Mocked;
-
 public class TestCommonToHttpServletRequest {
   @Test
   public void testConstructFormTrue() {
@@ -63,24 +58,11 @@ public class TestCommonToHttpServletRequest {
   }
 
   @Test
-  public void testConstructNormal(@Mocked RestParam param1, @Mocked RestParam param2,
-      @Mocked PartProcessor partProcessor) {
-    List<RestParam> restParams = new ArrayList<>();
-    restParams.add(param1);
-    restParams.add(param2);
-    new Expectations() {
-      {
-        param1.getParamProcessor();
-        result = partProcessor;
-        param1.getParamName();
-        result = "test1";
-        param2.getParamProcessor();
-        result = partProcessor;
-        param2.getParamName();
-        result = "test2";
-      }
-    };
-    HttpServletRequest request = new CommonToHttpServletRequest(null, null, null, null, false, restParams);
+  public void testConstructNormal() {
+    List<String> fileKeys = new ArrayList<>();
+    fileKeys.add("test1");
+    fileKeys.add("test2");
+    HttpServletRequest request = new CommonToHttpServletRequest(null, null, null, null, false, fileKeys);
     Assert.assertEquals(2, ((CommonToHttpServletRequest) request).getFileKeys().size());
     Assert.assertEquals("test1", ((CommonToHttpServletRequest) request).getFileKeys().get(0));
     Assert.assertEquals("test2", ((CommonToHttpServletRequest) request).getFileKeys().get(1));
@@ -270,25 +252,12 @@ public class TestCommonToHttpServletRequest {
   }
 
   @Test
-  public void testGetParts(@Mocked RestParam param1, @Mocked RestParam param2,
-      @Mocked PartProcessor partProcessor) {
-    List<RestParam> restParams = new ArrayList<>();
-    restParams.add(param1);
-    restParams.add(param2);
+  public void testGetParts() {
+    List<String> restParams = new ArrayList<>();
+    restParams.add("test1");
+    restParams.add("test2");
     File file1 = new File("file1.txt");
     File file2 = new File("file2.txt");
-    new Expectations() {
-      {
-        param1.getParamProcessor();
-        result = partProcessor;
-        param1.getParamName();
-        result = "test1";
-        param2.getParamProcessor();
-        result = partProcessor;
-        param2.getParamName();
-        result = "test2";
-      }
-    };
     File[] files = {file1, file2};
     List<File> list = Arrays.asList(files);
     Map<String, Object> objectMap = new HashMap<>();
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/OperationGenerator.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/OperationGenerator.java
index cd3b0f5..feacd86 100644
--- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/OperationGenerator.java
+++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/OperationGenerator.java
@@ -359,7 +359,7 @@ public class OperationGenerator {
     }
   }
 
-  // if is list<?> check and get respond type
+  // check whether is ArrayList , LinkedArrayList ...  or not
   private Type checkAndGetType(Type type) {
     if (ParameterizedType.class.isAssignableFrom(type.getClass())) {
       ParameterizedType targetType = (ParameterizedType) type;
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/ConverterMgr.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/ConverterMgr.java
index e86a55e..faf65ec 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/ConverterMgr.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/ConverterMgr.java
@@ -118,7 +118,7 @@ public class ConverterMgr {
     return null;
   }
 
-  // if is list<?> check and get respond type
+  // check whether is ArrayList , LinkedArrayList ...  or not
   private Type checkAndGetType(Type type) {
     if (ParameterizedType.class.isAssignableFrom(type.getClass())) {
       ParameterizedType targetType = (ParameterizedType) type;