projects
search condition metadata
Usage

Usage

Generate MetaData

This is a functionality that generates JSON-format MetaData for domain objects using the @MetaData and @MetaDataField annotations.

Example

Here is an example of metadata generation for the 'TestOrder' domain class.

Default

public class MetaDataGeneratorTest {
 
    @Test
    @DisplayName("Generates metadata from a valid domain class")
    public void testGenerator_whenNormalParam_thenSuccess() {
 
        String result = MetaDataGenerator.generate(TestOrder.class);
 
        System.out.println("metadata : " + result);
 
        assertThat(result).isNotNull().isNotEmpty();
 
    }
 
}

Result

metadata : [
  {
    "name": "description",
    "type": "string",
    "operators": ["=", "!=", "in", "not in", "regex", "wildcard"]
  },
  {
    "name": "customer.user.id",
    "type": "number",
    "operators": ["=", "!=", ">=", "<=", ">", "<"]
  },
  {
    "name": "customer.user.name",
    "type": "string",
    "operators": ["=", "!=", "in", "not in", "regex", "wildcard"]
  },
  {
    "name": "customer.description",
    "type": "string",
    "operators": ["=", "!=", "in", "not in", "regex", "wildcard"]
  },
  {
    "name": "products.name",
    "type": "string",
    "operators": ["=", "!=", "in", "not in", "regex", "wildcard"]
  },
  {
    "name": "products.price",
    "type": "number",
    "operators": ["=", "!=", ">=", "<=", ">", "<"]
  },
  {
    "name": "shippingInfo.productId",
    "type": "number",
    "operators": ["=", "!=", ">=", "<=", ">", "<"]
  },
  {
    "name": "shippingInfo.quantity",
    "type": "string",
    "operators": ["=", "!=", "in", "not in", "regex", "wildcard"]
  },
  {
    "name": "shippingInfo.wrapping.style",
    "type": "string",
    "operators": ["=", "!=", "in", "not in", "regex", "wildcard"]
  }
]

Specifying a Value Directly Using @MetaDataField

You can use the @MetaDataField annotation when you want to use a separate value other than the one that defaults.

The metadata field annotation is only applied to the last primitive-type field of the domain object.

If the annotation is added to a non-primitive type, it will not work and will be ignored.

Proper Functioning

public class TestUser {
 
    @MetaDataField(name = "uuid", type = "number", operators = {"=", "!="})
    private Long id;
 
    private String name;
 
}

Ignored

public class TestOrder {
 
    private String description;
 
    // @MetaDataField Ignored Cases
    @MetaDataField(name = "king", type = "string", operators = {"=", "!="})
    private TestCustomer customer;
 
    private List<TestProduct> products;
 
    private Map<String, TestShippingInfo> shippingInfo;
}

Result

metadata : [
  {
    "name": "description",
    "type": "string",
    "operators": ["=", "!=", "in", "not in", "regex", "wildcard"]
  },
  { "name": "customer.user.uuid", "type": "number", "operators": ["=", "!="] }, <---- The point where the @MetaDataField was applied
  {
    "name": "customer.user.name",
    "type": "string",
    "operators": ["=", "!=", "in", "not in", "regex", "wildcard"]
  },
  {
    "name": "customer.description",
    "type": "string",
    "operators": ["=", "!=", "in", "not in", "regex", "wildcard"]
  },
  {
    "name": "products.name",
    "type": "string",
    "operators": ["=", "!=", "in", "not in", "regex", "wildcard"]
  },
  {
    "name": "products.price",
    "type": "number",
    "operators": ["=", "!=", ">=", "<=", ">", "<"]
  },
  {
    "name": "shippingInfo.productId",
    "type": "number",
    "operators": ["=", "!=", ">=", "<=", ">", "<"]
  },
  {
    "name": "shippingInfo.quantity",
    "type": "string",
    "operators": ["=", "!=", "in", "not in", "regex", "wildcard"]
  },
  {
    "name": "shippingInfo.wrapping.style",
    "type": "string",
    "operators": ["=", "!=", "in", "not in", "regex", "wildcard"]
  }
]

Store metadata using a container

Example

You can store the generated MetaData in the MetaDataContainer along with a unique key and retrieve it based on the key when needed.

Default

@MetaData
public class Order {
 
    @MetaDataField(name = "redefine_description", type = "number", operators = { "=", "!=", ">" })
    private String description;
 
    private Product product;
 
    private Customer customer;
}
ℹ️

If you do not specify a separate key, the default key is set to the package including the class name.

ℹ️

The current example was based on a project using the Spring framework, but it can also be used in projects that do not use the Spring framework.

@SpringBootApplication
public class SpringSearchConditionMetadataGeneratorSampleApplication {
 
	public static void main(String[] args) throws ClassNotFoundException {
		SpringApplication.run(SpringSearchConditionMetadataGeneratorSampleApplication.class, args);
 
		MetaDataContainer metaDataContainer = MetaDataContainer.getInstance();
		metaDataContainer.setBasePackage("io.github.mainmethod0126.springsearchconditionmetadatageneratorsample");
		metaDataContainer.scan();
 
        // Since no separate key value was specified for the @MetaData annotation used in the Order class, it attempts to look up by the name of the Order class.
        System.out.println("metadata : " + metaDataContainer.get(Order.class.getName()));
	}
}
Result
metadata :[
  {
    "name": "redefine_description",
    "type": "number",
    "operators": ["=", "!=", ">"]
  },
  {
    "name": "product.name",
    "type": "string",
    "operators": ["=", "!=", "in", "not in", "regex", "wildcard"]
  },
  {
    "name": "product.price",
    "type": "number",
    "operators": ["=", "!=", ">=", "<=", ">", "<"]
  },
  {
    "name": "customer.user.id",
    "type": "number",
    "operators": ["=", "!=", ">=", "<=", ">", "<"]
  },
  {
    "name": "customer.user.name",
    "type": "string",
    "operators": ["=", "!=", "in", "not in", "regex", "wildcard"]
  },
  {
    "name": "customer.description",
    "type": "string",
    "operators": ["=", "!=", "in", "not in", "regex", "wildcard"]
  }
]

Use @MetaData key()

@MetaData(key = "test_order")
public class Order {
 
    @MetaDataField(name = "redefine_description", type = "number", operators = { "=", "!=", ">" })
    private String description;
 
    private Product product;
 
    private Customer customer;
}
@SpringBootApplication
public class SpringSearchConditionMetadataGeneratorSampleApplication {
 
	public static void main(String[] args) throws ClassNotFoundException {
		SpringApplication.run(SpringSearchConditionMetadataGeneratorSampleApplication.class, args);
 
		MetaDataContainer metaDataContainer = MetaDataContainer.getInstance();
		metaDataContainer.setBasePackage("io.github.mainmethod0126.springsearchconditionmetadatageneratorsample");
		metaDataContainer.scan();
 
        // Since a separate key value was specified for the @MetaData annotation used in the Order class, it looks up by that key value.
        System.out.println("metadata : " + metaDataContainer.get("test_order"));
	}
}
Result
metadata :[
  {
    "name": "redefine_description",
    "type": "number",
    "operators": ["=", "!=", ">"]
  },
  {
    "name": "product.name",
    "type": "string",
    "operators": ["=", "!=", "in", "not in", "regex", "wildcard"]
  },
  {
    "name": "product.price",
    "type": "number",
    "operators": ["=", "!=", ">=", "<=", ">", "<"]
  },
  {
    "name": "customer.user.id",
    "type": "number",
    "operators": ["=", "!=", ">=", "<=", ">", "<"]
  },
  {
    "name": "customer.user.name",
    "type": "string",
    "operators": ["=", "!=", "in", "not in", "regex", "wildcard"]
  },
  {
    "name": "customer.description",
    "type": "string",
    "operators": ["=", "!=", "in", "not in", "regex", "wildcard"]
  }
]