{"id":28412708,"url":"https://github.com/vbauer/jackdaw","last_synced_at":"2025-06-24T13:30:48.989Z","repository":{"id":28856168,"uuid":"32380229","full_name":"vbauer/jackdaw","owner":"vbauer","description":"Java Annotation Processor which allows to simplify development","archived":false,"fork":false,"pushed_at":"2024-10-03T18:47:28.000Z","size":355,"stargazers_count":315,"open_issues_count":4,"forks_count":32,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-06-03T11:55:09.573Z","etag":null,"topics":["annotation-processor","apt","java"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vbauer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-03-17T08:20:55.000Z","updated_at":"2025-05-02T16:42:03.000Z","dependencies_parsed_at":"2023-01-14T13:36:52.660Z","dependency_job_id":null,"html_url":"https://github.com/vbauer/jackdaw","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/vbauer/jackdaw","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vbauer%2Fjackdaw","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vbauer%2Fjackdaw/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vbauer%2Fjackdaw/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vbauer%2Fjackdaw/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vbauer","download_url":"https://codeload.github.com/vbauer/jackdaw/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vbauer%2Fjackdaw/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261685270,"owners_count":23194076,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["annotation-processor","apt","java"],"created_at":"2025-06-02T23:44:50.051Z","updated_at":"2025-06-24T13:30:48.964Z","avatar_url":"https://github.com/vbauer.png","language":"Java","readme":"# Jackdaw [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-Jackdaw-brightgreen.svg?style=flat)](http://android-arsenal.com/details/1/1655) [![Build Status](https://travis-ci.org/vbauer/jackdaw.svg)](https://travis-ci.org/vbauer/jackdaw) [![Maven](https://img.shields.io/github/tag/vbauer/jackdaw.svg?label=maven)](https://jitpack.io/#vbauer/jackdaw)\n\n\u003cimg align=\"right\" style=\"margin-left: 15px\" width=\"300\" height=\"243\" src=\"jackdaw-misc/jackdaw.png\" /\u003e\n\n**Jackdaw** is a Java [Annotation Processor](http://docs.oracle.com/javase/7/docs/api/javax/annotation/processing/Processor.html)\nwhich allows to simplify Java/Android development and prevents writing of tedious code.\n\nJackdaw was inspired by [Lombok](http://projectlombok.org) project, but in comparison with Lombok:\n\n* it does not need to have an extra plugin in IDE\n* it does not modify the existing source code\n\n\n## Features\n\n**Jackdaw** supports the following compile time annotations:\n\n\u003cul\u003e\n    \u003cli\u003e\u003ca href=\"#jadapter\"\u003e@JAdapter\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#jbean\"\u003e@JBean\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#jbuilder\"\u003e@JBuilder\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#jclassdescriptor\"\u003e@JClassDescriptor\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#jcomparator\"\u003e@JComparator\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#jfactorymethod\"\u003e@JFactoryMethod\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#jfunction\"\u003e@JFunction\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#jignore\"\u003e@JIgnore\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#jmessage\"\u003e@JMessage\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#jpredicate\"\u003e@JPredicate\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#jrepeatable\"\u003e@JRepeatable\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#jservice\"\u003e@JService\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#jsupplier\"\u003e@JSupplier\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\n\n## Setup\n\n**Jackdaw** uses [JitPack.io](https://jitpack.io) for distribution, so\nyou need to configure JitPack's Maven repository to fetch artifacts (dependencies).\n\nIt is necessary to make dependency on `jackdaw-core`.\nThis module contains compile time annotations which will be used to give a hints for APT.\nModule `jackdaw-apt` contains annotation processor and all correlated logic.\n\n### Maven\n\nRepositories section:\n```xml\n\u003crepositories\u003e\n    \u003crepository\u003e\n        \u003cid\u003ejitpack.io\u003c/id\u003e\n        \u003curl\u003ehttps://jitpack.io\u003c/url\u003e\n    \u003c/repository\u003e\n\u003c/repositories\u003e\n```\n\nDependencies section:\n```xml\n\u003cdependencies\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003ecom.github.vbauer.jackdaw\u003c/groupId\u003e\n        \u003cartifactId\u003ejackdaw-core\u003c/artifactId\u003e\n        \u003cversion\u003e${jackdaw.version}\u003c/version\u003e\n    \u003c/dependency\u003e\n\u003c/dependencies\u003e\n```\n\nAfter that, you need to configure `maven-compiler-plugin`:\n```xml\n\u003cbuild\u003e\n    \u003cplugins\u003e\n        \u003cplugin\u003e\n            \u003cgroupId\u003eorg.apache.maven.plugins\u003c/groupId\u003e\n            \u003cartifactId\u003emaven-compiler-plugin\u003c/artifactId\u003e\n            \u003cversion\u003e${maven.compiler.plugin.version}\u003c/version\u003e\n            \u003cconfiguration\u003e\n                \u003cforceJavacCompilerUse\u003etrue\u003c/forceJavacCompilerUse\u003e\n                \u003cannotationProcessorPaths\u003e\n                    \u003cannotationProcessorPath\u003e\n                        \u003cgroupId\u003ecom.github.vbauer.jackdaw\u003c/groupId\u003e\n                        \u003cartifactId\u003ejackdaw-apt\u003c/artifactId\u003e\n                        \u003cversion\u003e${jackdaw.version}\u003c/version\u003e\n                    \u003c/annotationProcessorPath\u003e\n                \u003c/annotationProcessorPaths\u003e\n            \u003c/configuration\u003e\n        \u003c/plugin\u003e\n    \u003c/plugins\u003e\n\u003c/build\u003e\n```\n\n### Gradle\n\nAdd custom repository:\n\n```groovy\nrepositories {\n    mavenCentral()\n    maven {\n        url 'https://jitpack.io'\n    }\n}\n```\n\nAdd `provided` scope to prevent `jackdaw-apt`:\n```groovy\nconfigurations {\n    provided\n}\n\nsourceSets {\n    main.compileClasspath += configurations.provided\n    test.compileClasspath += configurations.provided\n    test.runtimeClasspath += configurations.provided\n}\n```\n\nSpecify needed dependencies:\n```\ndependencies {\n    compile 'com.github.vbauer.jackdaw:jackdaw-core:1.0.9'\n    provided 'com.github.vbauer.jackdaw:jackdaw-apt:1.0.9'\n}\n```\n\n\n## Configuration\n\nAvailable parameters for annotation processor:\n\n* **addSuppressWarningsAnnotation** - Add `@SuppressWarnings(\"all\")` annotation on all generated classes to prevent unnecessary issues of IDE inspections (default value is `true`).\n* **addGeneratedAnnotation** - Add `@Generated` annotation on all generated classes to have possibility skip execution of static code analysis (default value is `true`).\n* **addGeneratedDate** - Add `date` parameter to `@Generated` annotation. It is also necessary to switch on `addGeneratedAnnotation` parameter (default value is `false`).\n\nExample configuration for maven-compiler-plugin:\n```xml\n\u003cconfiguration\u003e\n    \u003ccompilerArgs\u003e\n        \u003carg\u003e-AaddGeneratedAnnotation=true\u003c/arg\u003e\n        \u003carg\u003e-AaddGeneratedDate=true\u003c/arg\u003e\n        \u003carg\u003e-AaddSuppressWarningsAnnotation=false\u003c/arg\u003e\n    \u003c/compilerArgs\u003e\n\u003c/configuration\u003e\n```\n\n\n## Annotations\n\nSome things that you need to know before exploring an examples:\n\n* Code style in the below examples was changed to minimize text in README.\n* Some annotations and imports were also removed to simplify understanding.\n* All generated classes will have the same package as original classes.\n\n\n### @JAdapter\n\n**@JAdapter** allows to create class with empty method implementations using some interface or class.\nUsing generated class, you can override only needed methods (like in Swing, ex: [MouseAdapter](http://docs.oracle.com/javase/7/docs/api/java/awt/event/MouseAdapter.html)).\n\nOriginal class `MouseListener`:\n```java\n@JAdapter\npublic interface MouseListener {\n    void onMove(int x, int y);\n    void onPressed(int button);\n}\n```\nGenerated class `MouseListenerAdapter`:\n```java\npublic class MouseListenerAdapter implements MouseListener {\n    public void onMove(final int x, final int y) {\n    }\n    public void onPresses(final int button) {\n    }\n}\n```\n\n\n### @JBean\n**@JBean** generates some boilerplate code that is normally associated with simple POJOs (Plain Old Java Objects) and beans:\n\n* getters for all non-static/private fields,\n* setters for all non-static/private/final fields,\n* and copy constructors from super class\n\nOriginal class `AbstractUserModel`:\n```java\n@JBean\npublic abstract class AbstractUserModel {\n    protected int id;\n    protected String username;\n    protected String password;\n    protected boolean admin;\n}\n```\nGenerated class `User`:\n```java\npublic class User extends AbstractUserModel {\n    public User() { super(); }\n\n    public void setId(final int id) { this.id = id; }\n    public void getId() { return id; }\n    \n    public String getUsername() { return username; }\n    public void setUsername(final String username) { this.username = username; }\n    \n    public String getPassword() { return password; }\n    public void setPassword(final String password) { this.password = password; }\n    \n    public boolean isAdmin() { return admin; }\n    public void setAdmin(final boolean admin) { this.admin = admin; }\n}\n```\n\nPrefix 'Abstract' and postfix 'Model' will be removed if they are presented.\n\n\n### @JBuilder\nThe **@JBuilder** annotation produces complex builder APIs for your classes.\n\nOriginal class `Company`:\n```java\n@JBuilder\npublic class Company {\n    private int id;\n    private String name;\n    private Set\u003cString\u003e descriptions;\n\n    public int getId() { return id; }\n    public void setId(final int id) { this.id = id; }\n\n    public String getName() { return name; }\n    public void setName(final String name) { this.name = name; }\n\n    public Set\u003cString\u003e getDescriptions() { return descriptions; }\n    public void setDescriptions(final Set\u003cString\u003e descriptions) { this.descriptions = descriptions; }\n}\n```\nGenerated class `CompanyBuilder`:\n```java\npublic class CompanyBuilder {\n    private int id;\n    private String name;\n    private Set\u003cString\u003e descriptions;\n\n    public static CompanyBuilder create() {\n        return new CompanyBuilder();\n    }\n    public CompanyBuilder id(final int id) {\n        this.id = id;\n        return this;\n    }\n    public CompanyBuilder name(final String name) {\n        this.name = name;\n        return this;\n    }\n    public CompanyBuilder descriptions(final Set\u003cString\u003e descriptions) {\n        this.descriptions = descriptions;\n        return this;\n    }\n    public Company build() {\n        final Company object = new Company();\n        object.setId(id);\n        object.setName(name);\n        object.setListed(listed);\n        object.setDescriptions(descriptions);\n        return object;\n    }\n}\n```\n\n`@JBuilder` lets you automatically produce the code required to have your class be instantiable with code such as:\n```java\nCompanyBuilder.create()\n    .id(1)\n    .name(\"John Smith\")\n    .descriptions(Collections.singleton(\"Good guy\"))\n    .build()\n```\n\n\n### @JClassDescriptor\nSometimes it is necessary to use reflection, so it will be useful to have some string constants.\n**@JClassDescriptor** generates it for you easily.\n\nAvailable parameters:\n\n* **fields** - generate information about fields (default is `true`).\n* **methods** - generate information about methods (default is `true`).\n\nOriginal class `Company`:\n```java\n@JClassDescriptor\npublic class Company {\n    private int id;\n    private String name;\n\n    public int getId() { return id; }\n    public void setId(final int id) { this.id = id; }\n\n    public String getName() { return name; }\n    public void setName(final String name) { this.name = name; }\n}\n```\nGenerated class `CompanyClassDescriptor`:\n```java\npublic final class CompanyClassDescriptor {\n    public static final String FIELD_ID = \"id\";\n    public static final String FIELD_NAME = \"name\";\n\n    public static final String METHOD_ID = \"getId\";\n    public static final String METHOD_SET_ID = \"setId\";\n    public static final String METHOD_NAME = \"getName\";\n    public static final String METHOD_SET_NAME = \"setName\";\n\n    private CompanyClassDescriptor() {\n        throw new UnsupportedOperationException();\n    }\n}\n```\n\n### @JComparator\nTo generated safe and well-coded comparator, you have to write a lot of boilerplate code.\n**@JComparator** annotation allows to simplify this situation.\nTo generate reverse order comparator, use parameter `reverse`.\nBy default, all generated comparators are null-safe. Use `nullable` parameter to generate not null-safe comparators.\n\nThere are several ways to generate comparator or group of comparators.\nIt depends on the annotation location:\n\n* **annotation on field** - generate comparator only for one specified field.\n* **annotation on method without args** - generate comparator using method with empty list of arguments and non-void return-value.\n* **annotation on class** - generate comparators using 2 previous strategies (for all fields and simple methods).\n\nOriginal class `Company`:\n```java\npublic class Company {\n    @JComparator(nullable = false) private String name;\n    private long revenue;\n    \n    public String getName() { return name; }\n    public void setName(final String name) { this.name = name; }\n\n    @JComparator public long getRevenue() { return revenue; }\n    public void setRevenue(final long revenue) { this.revenue = revenue; }\n}\n```\nGenerated class `CompanyComparators`:\n```java\npublic final class CompanyComparators {\n    public static final Comparator\u003cCompany\u003e NAME = new Comparator\u003cCompany\u003e() {\n        public int compare(final Company o1, final Company o2) {\n            final String v1 = o1.getName();\n            final String v2 = o2.getName();\n            return v1.compareTo(v2);\n        }\n    };\n    public static final Comparator\u003cCompany\u003e REVENUE = new Comparator\u003cCompany\u003e() {\n        public int compare(final Company o1, final Company o2) {\n            final Long v1 = o1 == null ? null : o1.getRevenue();\n            final Long v2 = o2 == null ? null : o2.getRevenue();\n            if (v1 == v2) {\n                return 0;\n            } else if (v1 == null) {\n                return -1;\n            } else if (v2 == null) {\n                return 1;\n            }\n            return v1.compareTo(v2);\n        }\n    };\n    private CompanyComparators() {\n        throw new UnsupportedOperationException();\n    }\n}\n```\n\n\n### @JFactoryMethod\n**@JFactoryMethod** allows to use pattern *Factory Method* for object instantiation.\nTo use this annotation it is necessary to have setters and default constructor in original class.\n\nAvailable parameters:\n\n* **method** - factory method name (default value is `\"create\"`).\n* **all** - use all fields of class in factory method (default value is `true`).\n* **arguments** - use only specified fields in factory method (it is an empty array by default).\n\nOriginal class `Company`:\n```java\n@JFactoryMethod\npublic class Company {\n    private int id;\n    private String name;\n\n    public int getId() { return id; }\n    public void setId(final int id) { this.id = id; }\n\n    public String getName() { return name; }\n    public void setName(final String name) { this.name = name; }\n}\n```\nGenerated class `CompanyFactory`:\n```java\npublic final class CompanyFactory {\n    private CompanyFactory() {\n        throw new UnsupportedOperationException();\n    }\n    public static Company create(final int id, final String name) {\n        final Company object = new Company();\n        object.setId(id);\n        object.setName(name);\n        return object;\n    }\n}\n```\n\n### @JFunction\n\nThe **@JFunction** annotation generates `Function` implementation to use functional-way for programming.\nYou can specify different function interfaces for implementation generation (`JFunctionType`):\n\n* **JAVA** - functions from Java 8 (`java.util.function.Function`)\n* **GUAVA** - Guava functions (`com.google.common.base.Function`)\n\nThere are several ways to generate function or group of functions.\nIt depends on the annotation location:\n\n* **annotation on field** - generate function only for one specified field.\n* **annotation on method without args** - generate function using method with empty list of arguments and non-void return-value.\n* **annotation on class** - generate functions using 2 previous strategies (for all fields and simple methods).\n\nOriginal class `Company`:\n```java\npublic class Company {\n    @JFunction private int id;\n    \n    public int getId() { return id; }\n    public void setId(final int id) { this.id = id; }\n}\n```\nGenerated class `CompanyFunctions`:\n```java\npublic final class CompanyFunctions {\n    public static final Function\u003cCompany, Integer\u003e ID = new Function\u003cCompany, Integer\u003e() {\n        public Integer apply(final Company input) {\n            return (input != null) ? input.getId() : null;\n        }\n    };\n}\n```\n\nBy default, all generated functions are null-safe. Use `nullable` parameter to generate not null-safe functions.\n\n\n### @JIgnore\n\nThe **@JIgnore** annotation allows to ignore classes or interfaces from Jackdaw's processing.\n\n\n### @JMessage\nThe **@JMessage** annotation does not generate any additional code, instead of this it prints information in logs during project compiling.\nIt could be useful to make some really meaningful notes for you or your team, instead of using TODOs in comments.\n\nAvailable parameters:\n\n* **value** - List of notes, that will be logged.\n* **type** - Logging level (default value is `Diagnostic.Kind.MANDATORY_WARNING`).\n* **details** - Add information about annotated element with note message (default value is `false`).\n* **after** - Show message only after the given date. It could be useful to specify deadline. Supported formats:\n    * yyyy-MM-dd\n    * yyyy/MM/dd\n    * dd-MM-yyyy\n    * dd/MM/yyyy\n* **before** - Show message only before the given date. It could be useful in some cases. Supported formats are them same as in previous parameter.\n\nExample:\n```java\n@JMessage({\n    \"Do not forget to remove this class in the next release\",\n    \"MouseListener interface will be used instead of it\"\n})\npublic abstract class AbstractMouseListener implements MouseListener {\n    // Some piece of code.\n}\n```\n\nPart of compilation output:\n```\n[INFO] --- maven-processor-plugin:2.2.4:process (process) @ jackdaw-sample ---\n[WARNING] diagnostic: warning: Do not forget to remove this class in the next release\n[WARNING] diagnostic: warning: MouseListener interface will be used instead of it\n```\n\nThis feature could be also useful in pair with CI servers (detect `[WARNING]` and make some additional actions).\n\n\n### @JPredicate\n\nThe **@JPredicate** annotation generates `Predicate` implementation to use functional-way for programming.\nYou can specify different predicate interfaces for implementation generation (`JPredicateType`):\n\n* **JAVA** - predicates from Java 8 (`java.util.function.Predicate`)\n* **GUAVA** - Guava predicates (`com.google.common.base.Predicate`)\n* **COMMONS** - predicates from Apache Commons Collections (`org.apache.commons.collections.Predicate`)\n\nThere are several ways to generate predicate or group of predicates.\nIt depends on the annotation location:\n\n* **annotation on field** - generate predicate only for one specified field.\n* **annotation on method without args** - generate predicate using method with empty list of arguments and non-void return-value.\n* **annotation on class** - generate predicate using 2 previous strategies (for all fields and simple methods).\n\nOriginal class `Company`:\n```java\npublic class Company {\n    @JPredicate(reverse = true) private boolean listed;\n}\n```\nGenerated class `CompanyPredicates`:\n```java\npublic final class CompanyPredicates {\n    public static final Predicate\u003cCompany\u003e LISTED = new Predicate\u003cCompany\u003e() {\n        public boolean apply(final Company input) {\n            return !input.isListed();\n        }\n    };\n}\n```\nTo generate reverse predicate, use parameter `reverse`.\nBy default, all generated predicates are null-safe. Use `nullable` parameter to generate not null-safe predicates.\n\n\n### @JRepeatable\n\nThere are some situations where you want to apply the same annotation to a declaration or type use.\nAs of the Java SE 8 release, repeating annotations enable you to do this.\nIf you don't/can't use Java 8, then **@JRepeatable** helps you to resolve this problem using extra list-annotation.\n\nOriginal annotation `@Role`:\n```java\n@JRepeatable\n@Retention(RetentionPolicy.CLASS)\n@Target(ElementType.TYPE)\npublic @interface Role {\n}\n```\nGenerated annotation `@RoleList`:\n```java\n@Retention(java.lang.annotation.RetentionPolicy.CLASS)\n@Target(java.lang.annotation.ElementType.TYPE)\npublic @interface RoleList {\n    Role[] value();\n}\n```\n\n\n### @JService\n\nJava annotation processors and other systems use [ServiceLoader](http://docs.oracle.com/javase/7/docs/api/java/util/ServiceLoader.html)\nto register implementations of well-known types using META-INF metadata.\nHowever, it is easy for a developer to forget to update or correctly specify the service descriptors.\nMetadata will be generated for any class annotated with **@JService**.\n\nExample:\n```java\npublic interface BaseType {}\n\n@JService(BaseType.class)\npublic class TypeA implements BaseType {}\n\n@JService(BaseType.class)\npublic class TypeB implements BaseType {}\n```\nGenerated file `META-INF/services/BaseType`:\n```java\nTypeA\nTypeB\n```\n\n\n### @JSupplier\n\nThe **@JSupplier** annotation generates `Supplier` implementation to use functional-way for programming.\nYou can specify different supplier interfaces for implementation generation (`JSupplierType`):\n\n* **GUAVA** - Guava suppliers (`com.google.common.base.Supplier`)\n* **JAVA** - suppliers from Java 8 (`java.util.function.Supplier`)\n\nThere are several ways to generate supplier or group of suppliers.\nIt depends on the annotation location:\n\n* **annotation on field** - generate supplier only for one specified field.\n* **annotation on method without args** - generate supplier using method with empty list of arguments and non-void return-value.\n* **annotation on class** - generate suppliers using 2 previous strategies (for all fields and simple methods).\n\nOriginal class `Company`:\n```java\npublic class Company {\n    @JSupplier public Integer id;\n    \n    public int getId() { return id; }\n    public void setId(int id) { this.id = id; }\n}\n```\nGenerated class `CompanySuppliers`:\n```java\npublic final class CompanySuppliers {\n    public static Supplier\u003cInteger\u003e getId(final Company o) {\n        return new Supplier\u003cInteger\u003e() {\n            public Integer get() {\n                return o.getId();\n            }\n        };\n    }\n}\n```\n\n\n## Extensions\n\n**Jackdaw** is based on APT processor which executes different code generators.\nEach code generator should implement interface [CodeGenerator](jackdaw-apt/src/main/java/com/github/vbauer/jackdaw/code/base/CodeGenerator.java)\n(or extends from [BaseCodeGenerator](jackdaw-apt/src/main/java/com/github/vbauer/jackdaw/code/base/BaseCodeGenerator.java) / [GeneratedCodeGenerator](jackdaw-apt/src/main/java/com/github/vbauer/jackdaw/code/base/GeneratedCodeGenerator.java)).\n\nSignature of CodeGenerator interface:\n```java\npublic interface CodeGenerator {\n\n    Class\u003c? extends Annotation\u003e getAnnotation();\n\n    void generate(CodeGeneratorContext context) throws Exception;\n\n    void onStart() throws Exception;\n\n    void onFinish() throws Exception;\n\n}\n```\n\nAll generators are loaded by Java [ServiceLoader](http://docs.oracle.com/javase/7/docs/api/java/util/ServiceLoader.html) mechanism,\nso you can add your custom generator in few steps:\n\n* Create new generator class. It must have no-argument constructor.\n* Create file META-INF/services/com.github.vbauer.jackdaw.code.base.CodeGenerator and put canonical name of you class in this file.\n\nThat's all!\n\n\n## Building from source\n\nJackdaw uses Maven for its build. \nTo build the complete project with all modules (including example project), run\n\n```bash\nmvn clean install\n```\n\nfrom the root of the project directory.\n\n\n## Might also like\n\n* [jconditions](https://github.com/vbauer/jconditions) - Extra conditional annotations for JUnit.\n* [caesar](https://github.com/vbauer/caesar) - Library that allows to create async beans from sync beans.\n* [houdini](https://github.com/vbauer/houdini) - Type conversion system for Spring framework.\n* [herald](https://github.com/vbauer/herald) - Log annotation for logging frameworks.\n* [commons-vfs2-cifs](https://github.com/vbauer/commons-vfs2-cifs) - SMB/CIFS provider for Commons VFS.\n* [avconv4java](https://github.com/vbauer/avconv4java) - Java interface to avconv tool.\n\n\n## License\n\nCopyright 2015 Vladislav Bauer\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nSee [LICENSE](LICENSE) file for details.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvbauer%2Fjackdaw","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvbauer%2Fjackdaw","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvbauer%2Fjackdaw/lists"}