io.swagger.annotations.Api Java Examples

The following examples show how to use io.swagger.annotations.Api. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: SwaggerConfiguration.java    From mica with GNU Lesser General Public License v3.0 6 votes vote down vote up
@Bean
public Docket createRestApi(ApplicationContext context,
							MicaSwaggerProperties properties) {
	// 组名为应用名
	String appName = context.getId();
	Docket docket = new Docket(DocumentationType.SWAGGER_2)
		.useDefaultResponseMessages(false)
		.globalOperationParameters(globalHeaders(properties))
		.apiInfo(apiInfo(appName, properties)).select()
		.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
		.paths(PathSelectors.any())
		.build();
	// 如果开启认证
	if (properties.getAuthorization().getEnabled()) {
		docket.securitySchemes(Collections.singletonList(apiKey(properties)));
		docket.securityContexts(Collections.singletonList(securityContext(properties)));
	}
	return docket;
}
 
Example #2
Source File: ExtendedSwaggerReader.java    From msf4j with Apache License 2.0 6 votes vote down vote up
protected Set<String> extractTags(Api api) {
    Set<String> output = new LinkedHashSet<>();

    boolean hasExplicitTags = false;
    for (String tag : api.tags()) {
        if (!"".equals(tag)) {
            hasExplicitTags = true;
            output.add(tag);
        }
    }
    if (!hasExplicitTags) {
        // derive tag from api path + description
        String tagString = api.value().replace("/", "");
        if (!"".equals(tagString)) {
            output.add(tagString);
        }
    }
    return output;
}
 
Example #3
Source File: ExtendedSwaggerReader.java    From msf4j with Apache License 2.0 6 votes vote down vote up
protected Class<?> getSubResource(Method method) {
    final Class<?> rawType = method.getReturnType();
    final Class<?> type;
    if (Class.class.equals(rawType)) {
        type = getClassArgument(method.getGenericReturnType());
        if (type == null) {
            return null;
        }
    } else {
        type = rawType;
    }

    if (type.getAnnotation(Api.class) != null) {
        return type;
    }

    // For sub-resources that are not annotated with  @Api, look for any HttpMethods.
    for (Method m : type.getMethods()) {
        if (extractOperationMethod(null, m, null) != null) {
            return type;
        }
    }

    return null;
}
 
Example #4
Source File: RestResourceProcessor.java    From camunda-bpm-swagger with Apache License 2.0 6 votes vote down vote up
@Override
public void process(final CtInterface<?> resourceInterface) {
  final CtAnnotation<Annotation> annotation = getFactory().Code().createAnnotation(getFactory().Code().createCtTypeReference(Api.class));
  final RestService restService = context.getServiceDocumentation().get(resourceInterface.getQualifiedName());
  if (restService != null) {
    String[] tags;
    if (restService.getTags().contains(",")) {
      tags = restService.getTags().split(",");
    } else {
      tags = new String[]{ restService.getTags() };
    }

  annotation
    // .addValue("tags", tags)
    .addValue("hidden", true);
  resourceInterface.addAnnotation(annotation);
} else {
    log.error("No documentation for resource {} found.", resourceInterface.getQualifiedName());
  }
}
 
Example #5
Source File: RestServiceProcessor.java    From camunda-bpm-swagger with Apache License 2.0 6 votes vote down vote up
@Override
public void process(final CtInterface<?> restServiceInterface) {

  final CtAnnotation<Annotation> annotation = getFactory().Code().createAnnotation(getFactory().Code().createCtTypeReference(Api.class));
  final String classFqn = restServiceInterface.getQualifiedName();
  final RestService restService = context.getServiceDocumentation().get(classFqn);

  if (restService != null) {
    annotation.addValue("tags", restService.getTags());
    restServiceInterface.addAnnotation(annotation);

    // Add path annotation if missing
    final Path pathAnnotation = restServiceInterface.getAnnotation(Path.class);
    if (pathAnnotation == null) {
      final CtAnnotation<Path> path = getFactory().Code().createAnnotation(getFactory().Code().createCtTypeReference(Path.class));
      path.addValue("value", restService.getPath());
      restServiceInterface.addAnnotation(path);
    }

    log.debug("Added @Api to {} [{}]", restServiceInterface.getQualifiedName(), classFqn);
  } else {
    log.error("No documentation found for {} [{}]", restServiceInterface.getQualifiedName(), classFqn);
  }
}
 
Example #6
Source File: DubboReaderExtension.java    From swagger-dubbo with Apache License 2.0 6 votes vote down vote up
@Override
public void applySchemes(ReaderContext context, Operation operation, Method method) {
	final List<Scheme> schemes = new ArrayList<Scheme>();
	final ApiOperation apiOperation = ReflectionUtils.getAnnotation(method, ApiOperation.class);
	final Api apiAnnotation = context.getCls().getAnnotation(Api.class);

	if (apiOperation != null) {
		schemes.addAll(parseSchemes(apiOperation.protocols()));
	}

	if (schemes.isEmpty() && apiAnnotation != null) {
		schemes.addAll(parseSchemes(apiAnnotation.protocols()));
	}

	for (Scheme scheme : schemes) {
		operation.scheme(scheme);
	}

}
 
Example #7
Source File: DubboReaderExtension.java    From swagger-dubbo with Apache License 2.0 6 votes vote down vote up
@Override
public void applyProduces(ReaderContext context, Operation operation, Method method) {
	final List<String> produces = new ArrayList<String>();
	final ApiOperation apiOperation = ReflectionUtils.getAnnotation(method, ApiOperation.class);

	if (apiOperation != null) {
		produces.addAll(parseStringValues(apiOperation.produces()));
	}

	if (produces.isEmpty()) {
		final Api apiAnnotation = context.getCls().getAnnotation(Api.class);
		if (apiAnnotation != null) {
			produces.addAll(parseStringValues(apiAnnotation.produces()));
		}
		produces.addAll(context.getParentProduces());
	}

	for (String produce : produces) {
		operation.produces(produce);
	}

}
 
Example #8
Source File: DubboReaderExtension.java    From swagger-dubbo with Apache License 2.0 6 votes vote down vote up
@Override
public void applyConsumes(ReaderContext context, Operation operation, Method method) {
	final List<String> consumes = new ArrayList<String>();
	final ApiOperation apiOperation = ReflectionUtils.getAnnotation(method, ApiOperation.class);

	if (apiOperation != null) {
		consumes.addAll(parseStringValues(apiOperation.consumes()));
	}

	if (consumes.isEmpty()) {
		final Api apiAnnotation = context.getCls().getAnnotation(Api.class);
		if (apiAnnotation != null) {
			consumes.addAll(parseStringValues(apiAnnotation.consumes()));
		}
		consumes.addAll(context.getParentConsumes());
	}

	for (String consume : consumes) {
		operation.consumes(consume);
	}

}
 
Example #9
Source File: RpcReaderExtension.java    From sofa-rpc with Apache License 2.0 6 votes vote down vote up
@Override
public void applySchemes(ReaderContext context, Operation operation, Method method) {
    final List<Scheme> schemes = new ArrayList<Scheme>();
    final ApiOperation apiOperation = ReflectionUtils.getAnnotation(method, ApiOperation.class);
    final Api apiAnnotation = context.getCls().getAnnotation(Api.class);

    if (apiOperation != null) {
        schemes.addAll(parseSchemes(apiOperation.protocols()));
    }

    if (schemes.isEmpty() && apiAnnotation != null) {
        schemes.addAll(parseSchemes(apiAnnotation.protocols()));
    }

    for (Scheme scheme : schemes) {
        operation.scheme(scheme);
    }

}
 
Example #10
Source File: RpcReaderExtension.java    From sofa-rpc with Apache License 2.0 6 votes vote down vote up
@Override
public void applyProduces(ReaderContext context, Operation operation, Method method) {
    final List<String> produces = new ArrayList<String>();
    final ApiOperation apiOperation = ReflectionUtils.getAnnotation(method, ApiOperation.class);

    if (apiOperation != null) {
        produces.addAll(parseStringValues(apiOperation.produces()));
    }

    if (produces.isEmpty()) {
        final Api apiAnnotation = context.getCls().getAnnotation(Api.class);
        if (apiAnnotation != null) {
            produces.addAll(parseStringValues(apiAnnotation.produces()));
        }
        produces.addAll(context.getParentProduces());
    }

    for (String produce : produces) {
        operation.produces(produce);
    }

}
 
Example #11
Source File: RpcReaderExtension.java    From sofa-rpc with Apache License 2.0 6 votes vote down vote up
@Override
public void applyConsumes(ReaderContext context, Operation operation, Method method) {
    final List<String> consumes = new ArrayList<String>();
    final ApiOperation apiOperation = ReflectionUtils.getAnnotation(method, ApiOperation.class);

    if (apiOperation != null) {
        consumes.addAll(parseStringValues(apiOperation.consumes()));
    }

    if (consumes.isEmpty()) {
        final Api apiAnnotation = context.getCls().getAnnotation(Api.class);
        if (apiAnnotation != null) {
            consumes.addAll(parseStringValues(apiAnnotation.consumes()));
        }
        consumes.addAll(context.getParentConsumes());
    }

    for (String consume : consumes) {
        operation.consumes(consume);
    }

}
 
Example #12
Source File: JaxrsApplicationTest.java    From typescript-generator with MIT License 6 votes vote down vote up
@Test
public void testNamespacingByAnnotation() {
    final Settings settings = TestUtils.settings();
    settings.outputFileType = TypeScriptFileType.implementationFile;
    settings.generateJaxrsApplicationInterface = true;
    settings.generateJaxrsApplicationClient = true;
    settings.restNamespacing = RestNamespacing.byAnnotation;
    settings.restNamespacingAnnotation = Api.class;
    final String output = new TypeScriptGenerator(settings).generateTypeScript(Input.from(OrganizationApplication.class));
    final String errorMessage = "Unexpected output: " + output;
    Assert.assertTrue(errorMessage, output.contains("class OrgApiClient implements OrgApi "));
    Assert.assertTrue(errorMessage, output.contains("class OrganizationApplicationClient implements OrganizationApplication "));
    Assert.assertTrue(errorMessage, !output.contains("class OrganizationsResourceClient"));
    Assert.assertTrue(errorMessage, !output.contains("class OrganizationResourceClient"));
    Assert.assertTrue(errorMessage, !output.contains("class PersonResourceClient"));
}
 
Example #13
Source File: Reader.java    From dorado with Apache License 2.0 6 votes vote down vote up
protected Set<String> extractTags(Api api) {
	Set<String> output = new LinkedHashSet<String>();

	boolean hasExplicitTags = false;
	for (String tag : api.tags()) {
		if (!"".equals(tag)) {
			hasExplicitTags = true;
			output.add(tag);
		}
	}
	if (!hasExplicitTags) {
		// derive tag from api path + description
		String tagString = api.value().replace("/", "");
		if (!"".equals(tagString)) {
			output.add(tagString);
		}
	}
	return output;
}
 
Example #14
Source File: Reader.java    From dorado with Apache License 2.0 6 votes vote down vote up
protected Class<?> getSubResource(Method method) {
	final Class<?> rawType = method.getReturnType();
	final Class<?> type;
	if (Class.class.equals(rawType)) {
		type = getClassArgument(method.getGenericReturnType());
		if (type == null) {
			return null;
		}
	} else {
		type = rawType;
	}

	if (type.getAnnotation(Api.class) != null) {
		return type;
	}

	// For sub-resources that are not annotated with @Api, look for any HttpMethods.
	for (Method m : type.getMethods()) {
		if (extractOperationMethod(null, m, null) != null) {
			return type;
		}
	}

	return null;
}
 
Example #15
Source File: SmartSwaggerDynamicGroupConfig.java    From smart-admin with MIT License 6 votes vote down vote up
private Predicate<RequestHandler> getControllerPredicate() {
    groupName = groupList.get(groupIndex);
    List<String> apiTags = groupMap.get(groupName);
    Predicate<RequestHandler> methodPredicate = (input) -> {
        Api api = null;
        Optional<Api> apiOptional = input.findControllerAnnotation(Api.class);
        if (apiOptional.isPresent()) {
            api = apiOptional.get();
        }
        List<String> tags = Arrays.asList(api.tags());
        if (api != null && apiTags.containsAll(tags)) {
            return true;
        }
        return false;
    };
    groupIndex++;
    return Predicates.and(RequestHandlerSelectors.withClassAnnotation(RestController.class), methodPredicate);
}
 
Example #16
Source File: Swagger2Config.java    From spring-boot-plus with Apache License 2.0 6 votes vote down vote up
@Bean
public Docket createRestApi() {
    // 获取需要扫描的包
    String[] basePackages = getBasePackages();
    ApiSelectorBuilder apiSelectorBuilder = new Docket(DocumentationType.SWAGGER_2)
            .apiInfo(apiInfo())
            .select();
    // 如果扫描的包为空,则默认扫描类上有@Api注解的类
    if (ArrayUtils.isEmpty(basePackages)) {
        apiSelectorBuilder.apis(RequestHandlerSelectors.withClassAnnotation(Api.class));
    } else {
        // 扫描指定的包
        apiSelectorBuilder.apis(basePackage(basePackages));
    }
    Docket docket = apiSelectorBuilder.paths(PathSelectors.any())
            .build()
            .enable(swaggerProperties.isEnable())
            .ignoredParameterTypes(ignoredParameterTypes)
            .globalOperationParameters(getParameters());
    return docket;
}
 
Example #17
Source File: SwaggerMoreDoclet.java    From swagger-more with Apache License 2.0 6 votes vote down vote up
private static void annotateApiAnn(ApiInfo info, AnnotationsAttribute attr, ConstPool constPool) {
    Annotation apiAnn = attr.getAnnotation(Api.class.getTypeName());
    MemberValue value;
    if (isNull(apiAnn)) {
        apiAnn = new Annotation(Api.class.getName(), constPool);
    }
    if (isNull(value = apiAnn.getMemberValue(ApiInfo.HIDDEN)) || !((BooleanMemberValue) value).getValue()) {
        apiAnn.addMemberValue(ApiInfo.HIDDEN, new BooleanMemberValue(info.hidden(), constPool));
    }
    ArrayMemberValue arrayMemberValue = (ArrayMemberValue) apiAnn.getMemberValue(TAGS);
    if (isNull(arrayMemberValue)) {
        arrayMemberValue = new ArrayMemberValue(constPool);
        arrayMemberValue.setValue(new MemberValue[1]);
    }
    StringMemberValue tagMemberValue = (StringMemberValue) arrayMemberValue.getValue()[0];
    if (isNull(tagMemberValue) || StringUtils.isEmpty(tagMemberValue.getValue())) {
        tagMemberValue = new StringMemberValue(info.tag(), constPool);
    }
    tagMemberValue.setValue(info.tag());
    arrayMemberValue.getValue()[0] = tagMemberValue;
    apiAnn.addMemberValue(TAGS, arrayMemberValue);
    attr.addAnnotation(apiAnn);
}
 
Example #18
Source File: AServiceApplication.java    From spring-cloud-consul-example with MIT License 5 votes vote down vote up
@Bean
public Docket docket() {
    ApiSelectorBuilder apiSelectorBuilder = new Docket(DocumentationType.SWAGGER_2).select();
    apiSelectorBuilder.apis(withClassAnnotation(Api.class));
    return apiSelectorBuilder
            .build()
            .pathMapping("/")
            .useDefaultResponseMessages(false)
            .apiInfo(new ApiInfo("Service A API Doc", "Service A API Doc", "1.0", "https://github.com/yidongnan/spring-cloud-consul-example",
                    new Contact("Michael", "https://github.com/yidongnan", "[email protected]"), null, null))
            .forCodeGeneration(true);
}
 
Example #19
Source File: B1ServiceApplication.java    From spring-cloud-netflix-example with MIT License 5 votes vote down vote up
@Bean
public Docket docket() {
    ApiSelectorBuilder apiSelectorBuilder = new Docket(DocumentationType.SWAGGER_2).select();
    apiSelectorBuilder.apis(withClassAnnotation(Api.class));
    return apiSelectorBuilder
            .build()
            .pathMapping("/")
            .useDefaultResponseMessages(false)
            .apiInfo(new ApiInfo("Service B API Doc", "Service B API Doc", "1.0", "https://github.com/yidongnan/spring-cloud-netflix-example",
                    new Contact("Michael", "https://github.com/yidongnan", "[email protected]"), null, null))
            .forCodeGeneration(true);
}
 
Example #20
Source File: ResourceReaderExtension.java    From mdw with Apache License 2.0 5 votes vote down vote up
@Override
public void applyTags(ReaderContext context, Operation operation, Method method) {
    super.applyTags(context, operation, method);

    Class<?> declaringClass = method.getDeclaringClass();
    Api apiAnnotation = declaringClass.getAnnotation(Api.class);
    if (apiAnnotation != null && apiAnnotation.value() != null && !apiAnnotation.value().isEmpty()) {
        operation.addTag(apiAnnotation.value());
    }
}
 
Example #21
Source File: RestApiResourceScanner.java    From brooklyn-server with Apache License 2.0 5 votes vote down vote up
private void addAnnotatedClasses(Set<Class<?>> output, Collection<Class<?>> classes) {
    for (Class<?> clz : classes) {
        if (clz.getAnnotation(Api.class) != null) {
            output.add(clz);
        }
        addAnnotatedClasses(output, Arrays.asList(clz.getInterfaces()));
    }
}
 
Example #22
Source File: SwaggerAccessLoggerParser.java    From hsweb-framework with Apache License 2.0 5 votes vote down vote up
@Override
public LoggerDefine parse(MethodInterceptorHolder holder) {
    Api api = holder.findAnnotation(Api.class);
    ApiOperation operation = holder.findAnnotation(ApiOperation.class);
    String action = "";
    if (api != null) {
        action = action.concat(api.value());
    }
    if (null != operation) {
        action = StringUtils.isEmpty(action) ? operation.value() : action + "-" + operation.value();
    }
    return new LoggerDefine(action, "");
}
 
Example #23
Source File: SwaggerAccessLoggerParser.java    From hsweb-framework with Apache License 2.0 5 votes vote down vote up
@Override
public boolean support(Class clazz, Method method) {

    Api api = AnnotationUtils.findAnnotation(clazz, Api.class);
    ApiOperation operation = AnnotationUtils.findAnnotation(method, ApiOperation.class);

    return api != null || operation != null;
}
 
Example #24
Source File: ApiRequestHandlerProvider.java    From swagger-more with Apache License 2.0 5 votes vote down vote up
@Override
public List<RequestHandler> requestHandlers() {
    return byPatternsCondition().sortedCopy(nullToEmptyList(serviceBeans).stream()
            .filter(bean -> AnnotatedElementUtils.hasAnnotation(bean.getInterfaceClass(), Api.class))
            .reduce(newArrayList(), toMappingEntries(), (o1, o2) -> o1)
            .stream().map(toRequestHandler()).collect(Collectors.toList()));
}
 
Example #25
Source File: SwaggerServiceModelGenerator.java    From camunda-bpm-swagger with Apache License 2.0 5 votes vote down vote up
@Override
@SneakyThrows
public JCodeModel generate() {
  final JDefinedClass c = camundaRestService.getDefinedClass();

  // class information
  c._extends(camundaRestService.getServiceImplClass());
  c.annotate(codeModel.ref(Path.class)).param("value", camundaRestService.getPath());

  final String tags = TagRespository.lookup(camundaRestService);
  camundaRestService.getRestService().setPath(camundaRestService.getPath());
  camundaRestService.getRestService().setTags(tags);
  camundaRestService.getRestService().setDescription(camundaRestService.getName());
  c.annotate(codeModel.ref(Api.class)).param("value", camundaRestService.getName()).param("tags", tags);

  // generate constructor
  for (final Constructor<?> constructor : camundaRestService.getServiceImplClass().getConstructors()) {
    new InvocationStep(c.constructor(constructor.getModifiers())).constructor(constructor);
  }

  // construct return type information
  final Map<Method, ReturnTypeInfo> returnTypes = Arrays.stream(camundaRestService.getServiceInterfaceClass().getDeclaredMethods()) // iterate over interface
      // methods
      .map(m -> new ReturnTypeInfo(camundaRestService.getModelRepository(), codeModel, m)
          .applyImplementationMethods(camundaRestService.getServiceImplClass().getDeclaredMethods())) // apply impl methods
      .collect(Collectors.toMap(r -> r.getMethod(), r -> r)); // build the map

  generateMethods(c, camundaRestService.getRestService(), returnTypes, NO_PREFIX);

  return this.codeModel;
}
 
Example #26
Source File: ApiProcessor.java    From servicecomb-java-chassis with Apache License 2.0 5 votes vote down vote up
private void setTags(SwaggerGenerator swaggerGenerator, Api api) {
  String[] tags = api.tags();
  for (String tagName : tags) {
    if (StringUtils.isEmpty(tagName)) {
      continue;
    }
    swaggerGenerator.addDefaultTag(tagName);
  }
}
 
Example #27
Source File: A1ServiceApplication.java    From spring-cloud-netflix-example with MIT License 5 votes vote down vote up
@Bean
public Docket docket() {
    ApiSelectorBuilder apiSelectorBuilder = new Docket(DocumentationType.SWAGGER_2).select();
    apiSelectorBuilder.apis(withClassAnnotation(Api.class));
    return apiSelectorBuilder
            .build()
            .pathMapping("/")
            .useDefaultResponseMessages(false)
            .apiInfo(new ApiInfo("Service A API Doc", "Service A API Doc", "1.0", "https://github.com/yidongnan/spring-cloud-netflix-example",
                    new Contact("Michael", "https://github.com/yidongnan", "[email protected]"), null, null))
            .forCodeGeneration(true);
}
 
Example #28
Source File: BServiceApplication.java    From spring-cloud-consul-example with MIT License 5 votes vote down vote up
@Bean
public Docket docket() {
    ApiSelectorBuilder apiSelectorBuilder = new Docket(DocumentationType.SWAGGER_2).select();
    apiSelectorBuilder.apis(withClassAnnotation(Api.class));
    return apiSelectorBuilder
            .build()
            .pathMapping("/")
            .useDefaultResponseMessages(false)
            .apiInfo(new ApiInfo("Service B API Doc", "Service B API Doc", "1.0", "https://github.com/yidongnan/spring-cloud-consul-example",
                    new Contact("Michael", "https://github.com/yidongnan", "[email protected]"), null, null))
            .forCodeGeneration(true);
}
 
Example #29
Source File: ControllerHelpers.java    From stategen with GNU Affero General Public License v3.0 5 votes vote down vote up
private static <M extends IMenu<M>> void scanControllerMenus(Set<Class<?>> controllerClassSet, Class<M> menuClz,
                                                             List<M> allControllerMenus) throws InstantiationException, IllegalAccessException {
    Set<String> controllerApiNames = new HashSet<String>();

    for (Class<?> controllerClass : controllerClassSet) {
        Api apiAnno = AnnotatedElementUtils.findMergedAnnotation(controllerClass, Api.class);
        Menu menuAnno = AnnotatedElementUtils.findMergedAnnotation(controllerClass, Menu.class);
        VisitCheck controllerVisitCheckAnno = AnnotatedElementUtils.findMergedAnnotation(controllerClass, VisitCheck.class);
        final String controllerName = StringUtil.trimRight(controllerClass.getSimpleName(), CONTROLLER_SUBFIX);
        
        String route = ControllerHelpers.getRoute(controllerClass,controllerName, false);
        route = StringUtil.startWithSlash(route);
        
        boolean isMenu = menuAnno != null && menuAnno.value();
        MenuType controllerVisitType = getMenuTypeByControllerName(controllerName, isMenu);
        VisitCheckType controllerVisitCheckType = VisitCheckType.getCheckType(controllerVisitCheckAnno != null);

        String apiName = apiAnno != null ? apiAnno.value() : null;
        if (StringUtil.isBlank(apiName)) {
            apiName = StringUtil.trimLeftFormRightTo(controllerName, StringUtil.UNDERLINE);
        }

        AssertUtil.mustNotContainsAndAdd(controllerApiNames, apiName, "菜单名称不能相同:" + apiName);
        M controllerMenu = IMenu.createMenu(menuClz, controllerName, null, null, apiName, route, controllerVisitType, controllerVisitCheckType);
        allControllerMenus.add(controllerMenu);

        String controllerUrl = getControllerUrl(controllerClass);
        scanMethodMenus(menuClz, controllerClass, controllerName, controllerMenu, controllerUrl);
    }
}
 
Example #30
Source File: ApiInfo.java    From swagger-more with Apache License 2.0 5 votes vote down vote up
private void readApi() {
    Api api = findAnnotation(Api.class);
    if (nonNull(api)) {
        hidden |= api.hidden();
        for (String tag : api.tags()) {
            if (!StringUtils.isEmpty(tag)) {
                this.tag = tag;
            }
        }
    }
}