Example #1
0
 private Object invokeFunction(
     Method method, Object customObj, Object source, String[][] parameters) throws Exception {
   Class<?>[] prmTypes = method.getParameterTypes();
   Object[] methodPrms = new Object[prmTypes.length];
   methodPrms[0] = source;
   for (int parameterNdx = 0, methodPrmNdx = 1;
       parameterNdx < parameters.length;
       parameterNdx++, methodPrmNdx++) {
     if (method.isVarArgs() && methodPrmNdx == prmTypes.length - 1) {
       Object array =
           Array.newInstance(
               prmTypes[methodPrmNdx].getComponentType(), parameters.length - parameterNdx);
       for (int arrayNdx = 0; parameterNdx < parameters.length; parameterNdx++, arrayNdx++) {
         String[] parts = parameters[parameterNdx];
         Array.set(
             array,
             arrayNdx,
             resolver.resolveClass(parts[0]).getConstructor(String.class).newInstance(parts[1]));
       }
       methodPrms[methodPrmNdx] = array;
     } else {
       String[] parts = parameters[parameterNdx];
       methodPrms[methodPrmNdx] =
           resolver.resolveClass(parts[0]).getConstructor(String.class).newInstance(parts[1]);
     }
   }
   return method.invoke(customObj, methodPrms);
 }
Example #2
0
 private boolean parametersMatchParameterList(Class<?>[] prmTypes, String[][] parameters) {
   int ndx = 0;
   while (ndx < prmTypes.length) {
     Class<?> prmType = prmTypes[ndx];
     if (ndx >= parameters.length) {
       return ndx == prmTypes.length - 1 && prmType.isArray();
     }
     if (ndx == prmTypes.length - 1
         && prmType.isArray()) { // Assume this only occurs for functions with var args
       Class<?> varArgClass = prmType.getComponentType();
       while (ndx < parameters.length) {
         Class<?> prmClass = resolver.resolveClass(parameters[ndx][0]);
         if (!varArgClass.isAssignableFrom(prmClass)) {
           return false;
         }
         ndx++;
       }
     } else {
       Class<?> prmClass = resolver.resolveClass(parameters[ndx][0]);
       if (!prmTypes[ndx].isAssignableFrom(prmClass)) {
         return false;
       }
     }
     ndx++;
   }
   return true;
 }
Example #3
0
  Object mapCustom(Object source, Class<?> sourceClass) {
    // The converter parameter is stored in a thread local variable, so
    // we need to parse the parameter on each invocation
    // ex: custom-converter-param="org.example.MyMapping,map"
    // className = org.example.MyMapping
    // operation = map
    String[] prms = getParameter().split(",");
    String className = prms[0];
    String operation = prms.length > 1 ? prms[1] : null;

    // now attempt to process any additional parameters passed along
    // ex:
    // custom-converter-param="org.example.MyMapping,substring,java.lang.Integer=3,java.lang.Integer=10"
    // className = org.example.MyMapping
    // operation = substring
    // parameters = ["java.lang.Integer=3","java.lang.Integer=10"]
    String[][] prmTypesAndValues;
    if (prms.length > 2) {
      // Break parameters down into types and values
      prmTypesAndValues = new String[prms.length - 2][2];
      for (int ndx = 0; ndx < prmTypesAndValues.length; ndx++) {
        String prm = prms[ndx + 2];
        String[] parts = prm.split("=");
        if (parts.length != 2) {
          throw new RuntimeException("Value missing for parameter " + prm);
        }
        prmTypesAndValues[ndx][0] = parts[0];
        prmTypesAndValues[ndx][1] = parts[1];
      }
    } else {
      prmTypesAndValues = null;
    }

    Object customObj;
    Method method;
    try {
      Class<?> customClass = resolver.resolveMandatoryClass(className);
      customObj = customClass.newInstance();

      // If a specific mapping operation has been supplied use that
      if (operation != null && prmTypesAndValues != null) {
        method = selectMethod(customClass, operation, sourceClass, prmTypesAndValues);
      } else if (operation != null) {
        method = customClass.getMethod(operation, sourceClass);
      } else {
        method = selectMethod(customClass, sourceClass);
      }
    } catch (Exception e) {
      throw new RuntimeException("Failed to load custom function", e);
    }

    // Verify that we found a matching method
    if (method == null) {
      throw new RuntimeException("No eligible custom function methods in " + className);
    }

    // Invoke the custom mapping method
    try {
      if (prmTypesAndValues != null) {
        return invokeFunction(method, customObj, source, prmTypesAndValues);
      } else {
        return method.invoke(customObj, source);
      }
    } catch (Exception e) {
      throw new RuntimeException("Error while invoking custom function", e);
    }
  }
Example #4
0
  protected XStream createXStream(ClassResolver resolver, ClassLoader classLoader) {
    if (xstreamDriver != null) {
      xstream = new XStream(xstreamDriver);
    } else {
      xstream = new XStream();
    }

    if (mode != null) {
      xstream.setMode(getModeFromString(mode));
    }

    ClassLoader xstreamLoader = xstream.getClassLoader();
    if (classLoader != null && xstreamLoader instanceof CompositeClassLoader) {
      ((CompositeClassLoader) xstreamLoader).add(classLoader);
    }

    try {
      if (this.implicitCollections != null) {
        for (Entry<String, String[]> entry : this.implicitCollections.entrySet()) {
          for (String name : entry.getValue()) {
            xstream.addImplicitCollection(resolver.resolveMandatoryClass(entry.getKey()), name);
          }
        }
      }

      if (this.aliases != null) {
        for (Entry<String, String> entry : this.aliases.entrySet()) {
          xstream.alias(entry.getKey(), resolver.resolveMandatoryClass(entry.getValue()));
          // It can turn the auto-detection mode off
          xstream.processAnnotations(resolver.resolveMandatoryClass(entry.getValue()));
        }
      }

      if (this.omitFields != null) {
        for (Entry<String, String[]> entry : this.omitFields.entrySet()) {
          for (String name : entry.getValue()) {
            xstream.omitField(resolver.resolveMandatoryClass(entry.getKey()), name);
          }
        }
      }

      if (this.converters != null) {
        for (String name : this.converters) {
          Class<Converter> converterClass = resolver.resolveMandatoryClass(name, Converter.class);
          Converter converter;

          Constructor<Converter> con = null;
          try {
            con = converterClass.getDeclaredConstructor(new Class[] {XStream.class});
          } catch (Exception e) {
            // swallow as we null check in a moment.
          }
          if (con != null) {
            converter = con.newInstance(xstream);
          } else {
            converter = converterClass.newInstance();
            try {
              Method method = converterClass.getMethod("setXStream", new Class[] {XStream.class});
              if (method != null) {
                ObjectHelper.invokeMethod(method, converter, xstream);
              }
            } catch (Throwable e) {
              // swallow, as it just means the user never add an XStream setter, which is optional
            }
          }

          xstream.registerConverter(converter);
        }
      }

      addDefaultPermissions(xstream);
      if (this.permissions != null) {
        // permissions ::= pterm (',' pterm)*   # consits of one or more terms
        // pterm       ::= aod? wterm           # each term preceded by an optional sign
        // aod         ::= '+' | '-'            # indicates allow or deny where allow if omitted
        // wterm       ::= a class name with optional wildcard characters
        addPermissions(xstream, permissions);
      }
    } catch (Exception e) {
      throw new RuntimeException("Unable to build XStream instance", e);
    }

    return xstream;
  }
Example #5
0
  private void parse(
      Swagger swagger, RestDefinition rest, String camelContextId, ClassResolver classResolver) {
    List<VerbDefinition> verbs = new ArrayList<>(rest.getVerbs());
    // must sort the verbs by uri so we group them together when an uri has multiple operations
    Collections.sort(verbs, new VerbOrdering());

    // we need to group the operations within the same tag, so use the path as default if not
    // configured
    String pathAsTag =
        rest.getTag() != null ? rest.getTag() : FileUtil.stripLeadingSeparator(rest.getPath());
    String summary = rest.getDescriptionText();

    if (ObjectHelper.isNotEmpty(pathAsTag)) {
      // add rest as tag
      Tag tag = new Tag();
      tag.description(summary);
      tag.name(pathAsTag);
      swagger.addTag(tag);
    }

    // gather all types in use
    Set<String> types = new LinkedHashSet<>();
    for (VerbDefinition verb : verbs) {
      String type = verb.getType();
      if (ObjectHelper.isNotEmpty(type)) {
        if (type.endsWith("[]")) {
          type = type.substring(0, type.length() - 2);
        }
        types.add(type);
      }
      type = verb.getOutType();
      if (ObjectHelper.isNotEmpty(type)) {
        if (type.endsWith("[]")) {
          type = type.substring(0, type.length() - 2);
        }
        types.add(type);
      }
      // there can also be types in response messages
      if (verb.getResponseMsgs() != null) {
        for (RestOperationResponseMsgDefinition def : verb.getResponseMsgs()) {
          type = def.getResponseModel();
          if (ObjectHelper.isNotEmpty(type)) {
            if (type.endsWith("[]")) {
              type = type.substring(0, type.length() - 2);
            }
            types.add(type);
          }
        }
      }
    }

    // use annotation scanner to find models (annotated classes)
    for (String type : types) {
      Class<?> clazz = classResolver.resolveClass(type);
      appendModels(clazz, swagger);
    }

    // used during gathering of apis
    List<Path> paths = new ArrayList<>();

    String basePath = rest.getPath();

    for (VerbDefinition verb : verbs) {

      // the method must be in lower case
      String method = verb.asVerb().toLowerCase(Locale.US);
      // operation path is a key
      String opPath = SwaggerHelper.buildUrl(basePath, verb.getUri());

      Operation op = new Operation();
      if (ObjectHelper.isNotEmpty(pathAsTag)) {
        // group in the same tag
        op.addTag(pathAsTag);
      }

      // add id as vendor extensions
      op.getVendorExtensions().put("x-camelContextId", camelContextId);
      op.getVendorExtensions().put("x-routeId", verb.getRouteId());

      Path path = swagger.getPath(opPath);
      if (path == null) {
        path = new Path();
        paths.add(path);
      }
      path = path.set(method, op);

      String consumes = verb.getConsumes() != null ? verb.getConsumes() : rest.getConsumes();
      if (consumes != null) {
        String[] parts = consumes.split(",");
        for (String part : parts) {
          op.addConsumes(part);
        }
      }

      String produces = verb.getProduces() != null ? verb.getProduces() : rest.getProduces();
      if (produces != null) {
        String[] parts = produces.split(",");
        for (String part : parts) {
          op.addProduces(part);
        }
      }

      if (verb.getDescriptionText() != null) {
        op.summary(verb.getDescriptionText());
      }

      for (RestOperationParamDefinition param : verb.getParams()) {
        Parameter parameter = null;
        if (param.getType().equals(RestParamType.body)) {
          parameter = new BodyParameter();
        } else if (param.getType().equals(RestParamType.form)) {
          parameter = new FormParameter();
        } else if (param.getType().equals(RestParamType.header)) {
          parameter = new HeaderParameter();
        } else if (param.getType().equals(RestParamType.path)) {
          parameter = new PathParameter();
        } else if (param.getType().equals(RestParamType.query)) {
          parameter = new QueryParameter();
        }

        if (parameter != null) {
          parameter.setName(param.getName());
          parameter.setAccess(param.getAccess());
          parameter.setDescription(param.getDescription());
          parameter.setRequired(param.getRequired());

          // set type on parameter
          if (parameter instanceof SerializableParameter) {
            SerializableParameter sp = (SerializableParameter) parameter;

            if (param.getDataType() != null) {
              sp.setType(param.getDataType());
            }
            if (param.getAllowableValues() != null) {
              sp.setEnum(param.getAllowableValues());
            }
          }

          // set schema on body parameter
          if (parameter instanceof BodyParameter) {
            BodyParameter bp = (BodyParameter) parameter;

            if (verb.getType() != null) {
              String ref = modelTypeAsRef(verb.getType(), swagger);
              if (ref != null) {
                bp.setSchema(new RefModel(ref));
              }
            }
          }

          op.addParameter(parameter);
        }
      }

      // if we have an out type then set that as response message
      if (verb.getOutType() != null) {
        Response response = new Response();
        Property prop = modelTypeAsProperty(verb.getOutType(), swagger);
        response.setSchema(prop);
        response.setDescription("Output type");
        op.addResponse("200", response);
      }

      // enrich with configured response messages from the rest-dsl
      for (RestOperationResponseMsgDefinition msg : verb.getResponseMsgs()) {
        Response response = null;
        if (op.getResponses() != null) {
          response = op.getResponses().get(msg.getCode());
        }
        if (response == null) {
          response = new Response();
        }
        if (ObjectHelper.isNotEmpty(msg.getResponseModel())) {
          Property prop = modelTypeAsProperty(msg.getResponseModel(), swagger);
          response.setSchema(prop);
        }
        response.setDescription(msg.getMessage());
        op.addResponse(msg.getCode(), response);
      }

      // add path
      swagger.path(opPath, path);
    }
  }