Java tutorial
/* * Copyright 2017 Huawei Technologies Co., Ltd * * Licensed 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.common.rest.definition; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.servicecomb.common.rest.codec.produce.ProduceProcessor; import io.servicecomb.common.rest.codec.produce.ProduceProcessorManager; import io.servicecomb.common.rest.definition.path.PathRegExp; import io.servicecomb.common.rest.definition.path.URLPathBuilder; import io.servicecomb.core.definition.OperationMeta; import io.servicecomb.foundation.vertx.http.HttpServletRequestEx; import io.swagger.models.Operation; import io.swagger.models.Swagger; import io.swagger.models.parameters.Parameter; import io.vertx.ext.web.impl.Utils; public class RestOperationMeta { private static final Logger LOGGER = LoggerFactory.getLogger(RestOperationMeta.class); protected OperationMeta operationMeta; protected List<String> produces; protected boolean formData; protected List<RestParam> paramList = new ArrayList<>(); // key??? protected Map<String, RestParam> paramMap = new LinkedHashMap<>(); // key?json private Map<String, ProduceProcessor> produceProcessorMap = new HashMap<>(); // ?mgrdefaultoperation???mgrdefault private ProduceProcessor defaultProcessor; protected String absolutePath; protected PathRegExp absolutePathRegExp; // URL path private URLPathBuilder pathBuilder; public void init(OperationMeta operationMeta) { this.operationMeta = operationMeta; Swagger swagger = operationMeta.getSchemaMeta().getSwagger(); Operation operation = operationMeta.getSwaggerOperation(); this.produces = operation.getProduces(); if (produces == null) { this.produces = swagger.getProduces(); } this.createProduceProcessors(); Method method = operationMeta.getMethod(); Type[] genericParamTypes = method.getGenericParameterTypes(); if (genericParamTypes.length != operation.getParameters().size()) { throw new Error("Param count is not equal between swagger and method, path=" + absolutePath); } // ?rest param for (int idx = 0; idx < genericParamTypes.length; idx++) { Parameter parameter = operation.getParameters().get(idx); Type genericParamType = genericParamTypes[idx]; if ("formData".equals(parameter.getIn())) { formData = true; } RestParam param = new RestParam(idx, parameter, genericParamType); addParam(param); } setAbsolutePath(concatPath(swagger.getBasePath(), operationMeta.getOperationPath())); } public boolean isFormData() { return formData; } public void setOperationMeta(OperationMeta operationMeta) { this.operationMeta = operationMeta; } // b/c/?url private String concatPath(String basePath, String operationPath) { return ("/" + nonNullify(basePath) + "/" + nonNullify(operationPath) + "/").replaceAll("/{2,}", "/"); } private String nonNullify(String path) { return path == null ? "" : path; } public String getAbsolutePath() { return this.absolutePath; } public void setAbsolutePath(String absolutePath) { this.absolutePath = absolutePath; this.absolutePathRegExp = createPathRegExp(absolutePath); this.pathBuilder = new URLPathBuilder(absolutePath, paramMap); } public PathRegExp getAbsolutePathRegExp() { return this.absolutePathRegExp; } public boolean isAbsoluteStaticPath() { return this.absolutePathRegExp.isStaticPath(); } protected PathRegExp createPathRegExp(String path) { if (path == null || path.equals("")) { throw new Error("null rest url is not supported"); } try { return new PathRegExp(path); } catch (Exception e) { LOGGER.error(e.getMessage()); return null; } } public RestParam getParamByName(String name) { return paramMap.get(name); } public RestParam getParamByIndex(int index) { return paramList.get(index); } public OperationMeta getOperationMeta() { return operationMeta; } // operation??produce processor protected void createProduceProcessors() { if (null == produces || produces.isEmpty()) { for (ProduceProcessor processor : ProduceProcessorManager.INSTANCE.values()) { this.produceProcessorMap.put(processor.getName(), processor); } } else { for (String produce : produces) { ProduceProcessor processor = ProduceProcessorManager.INSTANCE.findValue(produce); if (processor == null) { LOGGER.error("produce {} is not supported", produce); continue; } this.produceProcessorMap.put(produce, processor); } } defaultProcessor = getDefaultOrFirstProcessor(); produceProcessorMap.putIfAbsent(MediaType.WILDCARD, defaultProcessor); produceProcessorMap.putIfAbsent(ProduceProcessorManager.DEFAULT_TYPE, ProduceProcessorManager.DEFAULT_PROCESSOR); } public URLPathBuilder getPathBuilder() { return this.pathBuilder; } public List<RestParam> getParamList() { return paramList; } private void addParam(RestParam param) { paramList.add(param); paramMap.put(param.getParamName(), param); } public ProduceProcessor findProduceProcessor(String type) { return this.produceProcessorMap.get(type); } // accept?produce processor? public ProduceProcessor ensureFindProduceProcessor(HttpServletRequestEx requestEx) { String acceptType = requestEx.getHeader(HttpHeaders.ACCEPT); return ensureFindProduceProcessor(acceptType); } public ProduceProcessor ensureFindProduceProcessor(String acceptType) { if (StringUtils.isEmpty(acceptType)) { return defaultProcessor; } List<String> mimeTyps = Utils.getSortedAcceptableMimeTypes(acceptType); for (String mime : mimeTyps) { ProduceProcessor processor = this.produceProcessorMap.get(mime); if (null != processor) { return processor; } } return null; } // ??processor private ProduceProcessor getDefaultOrFirstProcessor() { ProduceProcessor processor = this.produceProcessorMap.get(ProduceProcessorManager.DEFAULT_TYPE); if (null == processor) { for (ProduceProcessor pp : this.produceProcessorMap.values()) { return pp; } } if (processor == null) { processor = ProduceProcessorManager.JSON_PROCESSOR; } return processor; } public String getHttpMethod() { return operationMeta.getHttpMethod(); } public List<String> getProduces() { return produces; } }