Initial commit

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/commit/f0884aeb
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/tree/f0884aeb
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/diff/f0884aeb

Branch: refs/heads/master
Commit: f0884aeb8414960e409ef0e2a09c1d2712e6d3e6
Parents: bdfc809
Author: Ralph Goers <[email protected]>
Authored: Sat Sep 2 19:18:04 2017 -0700
Committer: Ralph Goers <[email protected]>
Committed: Sat Sep 2 19:18:04 2017 -0700

----------------------------------------------------------------------
 NOTICE.txt                                      |     5 +-
 RELEASE-NOTES.md                                |    17 +
 log4j-audit-distribution/pom.xml                |   273 +
 log4j-audit-distribution/src/assembly/bin.xml   |    59 +
 log4j-audit-distribution/src/assembly/src.xml   |    81 +
 log4j-audit/log4j-audit-api/pom.xml             |    86 +
 .../log4j/audit/AbstractEventLogger.java        |   206 +
 .../logging/log4j/audit/ActivityLogger.java     |    49 +
 .../apache/logging/log4j/audit/AuditEvent.java  |    41 +
 .../log4j/audit/AuditExceptionHandler.java      |    33 +
 .../apache/logging/log4j/audit/AuditLogger.java |    50 +
 .../logging/log4j/audit/AuditMessage.java       |    58 +
 .../logging/log4j/audit/LogEventFactory.java    |   385 +
 .../log4j/audit/annotation/Constraint.java      |    33 +
 .../log4j/audit/annotation/Constraints.java     |    31 +
 .../log4j/audit/annotation/MaxLength.java       |    31 +
 .../log4j/audit/annotation/RequestContext.java  |    42 +
 .../annotation/RequestContextConstraints.java   |    31 +
 .../log4j/audit/annotation/Required.java        |    30 +
 .../log4j/audit/catalog/CatalogManager.java     |    42 +
 .../log4j/audit/catalog/CatalogManagerImpl.java |   150 +
 .../logging/log4j/audit/constant/Column.java    |   102 +
 .../log4j/audit/constant/Environment.java       |    45 +
 .../log4j/audit/constant/QueryParameter.java    |    41 +
 .../logging/log4j/audit/dto/AuditDto.java       |    87 +
 .../log4j/audit/exception/AuditException.java   |    37 +
 .../audit/generator/AccessorDefinition.java     |   153 +
 .../log4j/audit/generator/ClassGenerator.java   |   355 +
 .../log4j/audit/generator/Constants.java        |    25 +
 .../audit/generator/ConstructorDefinition.java  |   122 +
 .../audit/generator/InterfacesGenerator.java    |   335 +
 .../log4j/audit/generator/MethodDefinition.java |   334 +
 .../log4j/audit/generator/Parameter.java        |    77 +
 .../audit/generator/VariableDefinition.java     |   149 +
 .../logging/log4j/audit/layout/AuditLayout.java |    20 +
 .../audit/util/JsonObjectMapperFactory.java     |   164 +
 .../logging/log4j/audit/util/NamingUtils.java   |    79 +
 .../logging/log4j/audit/util/StringUtil.java    |    31 +
 .../logging/log4j/audit/AuditLoggerTest.java    |   115 +
 .../logging/log4j/audit/TransferTest.java       |   162 +
 .../log4j/audit/catalog/CatalogManagerTest.java |    35 +
 .../audit/catalog/StringCatalogReader.java      |   228 +
 .../logging/log4j/audit/event/Transfer.java     |    60 +
 .../generator/TestInterfacesGenerator.java      |    68 +
 .../log4j/audit/util/NamingUtilsTest.java       |    37 +
 .../resources/InterfacesGeneratorContext.xml    |    64 +
 .../src/test/resources/catalog.zip              |   Bin 0 -> 964 bytes
 .../resources/interfacesGenerator.properties    |    14 +
 .../src/test/resources/log4j2-test.xml          |    41 +
 log4j-audit/log4j-audit-api/testCatalog.json    |   193 +
 log4j-audit/log4j-audit-maven-plugin/pom.xml    |   156 +
 .../src/it/default-generate/pom.xml             |   154 +
 .../src/main/resources/catalog.json             |   193 +
 .../src/it/default-generate/verify.groovy       |    19 +
 .../src/it/settings.xml                         |    54 +
 .../logging/log4j/audit/plugin/AuditMojo.java   |   121 +
 .../src/main/resources/log4j2.xml               |    29 +
 log4j-audit/log4j-audit-war/pom.xml             |   187 +
 .../logging/log4j/audit/service/Versions.java   |    26 +
 .../config/ApplicationConfiguration.java        |    23 +
 .../service/config/ConfigurationService.java    |    33 +
 .../audit/service/config/SwaggerConfig.java     |    63 +
 .../audit/service/config/WebAppInitializer.java |    48 +
 .../audit/service/config/WebMvcAppContext.java  |   176 +
 .../service/controller/AuditController.java     |    61 +
 .../RestResponseEntityExceptionHandler.java     |    55 +
 .../security/LocalAuthorizationInterceptor.java |    57 +
 .../src/main/resources/log4j2.xml               |    80 +
 log4j-audit/pom.xml                             |    33 +
 log4j-catalog/log4j-catalog-api/pom.xml         |   105 +
 .../logging/log4j/catalog/api/Attribute.java    |   315 +
 .../logging/log4j/catalog/api/CatalogData.java  |   115 +
 .../log4j/catalog/api/CatalogReader.java        |    72 +
 .../log4j/catalog/api/CatalogWriter.java        |    20 +
 .../logging/log4j/catalog/api/Category.java     |   154 +
 .../logging/log4j/catalog/api/Constraint.java   |    69 +
 .../log4j/catalog/api/ConstraintType.java       |    45 +
 .../logging/log4j/catalog/api/DataType.java     |    60 +
 .../apache/logging/log4j/catalog/api/Event.java |   185 +
 .../log4j/catalog/api/EventAttribute.java       |    67 +
 .../logging/log4j/catalog/api/ListResponse.java |    43 +
 .../logging/log4j/catalog/api/Product.java      |   151 +
 .../apache/logging/log4j/catalog/api/Type.java  |    27 +
 .../logging/log4j/catalog/api/Versions.java     |    26 +
 .../annotation/ConditionOnPropertyExists.java   |    37 +
 .../api/annotation/PropertyExistsCondition.java |    38 +
 .../catalog/api/dao/AbstractCatalogReader.java  |    77 +
 .../log4j/catalog/api/dao/CatalogDao.java       |    64 +
 .../catalog/api/dao/ClassPathCatalogReader.java |    89 +
 .../catalog/api/dao/FileCatalogReader.java      |    90 +
 .../catalog/api/dao/JsonCatalogReader.java      |    67 +
 .../catalog/api/exception/CatalogException.java |    41 +
 .../exception/CatalogModificationException.java |    41 +
 .../api/exception/CatalogNotFoundException.java |    41 +
 .../api/exception/CatalogReadException.java     |    41 +
 .../api/exception/CatalogWriteException.java    |    41 +
 .../exception/ConstraintCreationException.java  |    41 +
 .../ConstraintValidationException.java          |    41 +
 .../api/exception/DuplicateNameException.java   |    41 +
 .../exception/InvalidEnvironmentException.java  |    41 +
 .../api/exception/InvalidSiteException.java     |    41 +
 .../api/exception/NameNotFoundException.java    |    41 +
 .../logging/log4j/catalog/api/package-info.java |    19 +
 .../plugins/CaseInsensitiveEnumConstraint.java  |    44 +
 .../catalog/api/plugins/ConstraintPlugins.java  |   105 +
 .../api/plugins/ConstraintTypeDeserializer.java |    54 +
 .../api/plugins/ConstraintTypeSerializer.java   |    51 +
 .../catalog/api/plugins/EnumConstraint.java     |    44 +
 .../api/plugins/MaxLengthConstraint.java        |    58 +
 .../catalog/api/plugins/MaxValueConstraint.java |    61 +
 .../api/plugins/MinLengthConstraint.java        |    58 +
 .../catalog/api/plugins/MinValueConstraint.java |    61 +
 .../catalog/api/plugins/PatternConstraint.java  |    41 +
 .../catalog/api/service/CatalogService.java     |    26 +
 .../log4j/catalog/api/util/StringUtils.java     |    35 +
 log4j-catalog/log4j-catalog-git/pom.xml         |   134 +
 .../log4j/catalog/git/config/ServiceConfig.java |    22 +
 .../log4j/catalog/git/config/package-info.java  |    19 +
 .../log4j/catalog/git/dao/GitCatalogDao.java    |   202 +
 .../log4j/catalog/git/dao/GitCatalogData.java   |    48 +
 .../log4j/catalog/git/dao/package-info.java     |    19 +
 .../logging/log4j/catalog/git/package-info.java |    19 +
 .../logging/log4j/catalog/git/CatalogTest.java  |   108 +
 .../git/config/ApplicationConfiguration.java    |    65 +
 .../src/test/resources/log4j2.xml               |    48 +
 log4j-catalog/log4j-catalog-jpa/pom.xml         |   257 +
 .../jpa/config/ApplicationConfiguration.java    |    34 +
 .../jpa/config/EclipseLinkDataSourceConfig.java |    73 +
 .../jpa/config/HibernatgeDataSourceConfig.java  |    69 +
 .../log4j/catalog/jpa/config/package-info.java  |    19 +
 .../jpa/converter/AttributeConverter.java       |    88 +
 .../jpa/converter/AttributeModelConverter.java  |    62 +
 .../jpa/converter/BooleanToStringConverter.java |    37 +
 .../jpa/converter/CategoryConverter.java        |    56 +
 .../jpa/converter/CategoryModelConverter.java   |    49 +
 .../jpa/converter/DataTypeConverter.java        |    38 +
 .../jpa/converter/DateTimeConverter.java        |    41 +
 .../catalog/jpa/converter/EventConverter.java   |    96 +
 .../jpa/converter/EventModelConverter.java      |    54 +
 .../catalog/jpa/converter/ProductConverter.java |    56 +
 .../jpa/converter/ProductModelConverter.java    |    49 +
 .../catalog/jpa/converter/package-info.java     |    19 +
 .../catalog/jpa/dao/AttributeRepository.java    |    22 +
 .../log4j/catalog/jpa/dao/BaseRepository.java   |    40 +
 .../catalog/jpa/dao/CategoryRepository.java     |    25 +
 .../catalog/jpa/dao/ConstraintRepository.java   |    23 +
 .../log4j/catalog/jpa/dao/EventRepository.java  |    22 +
 .../jpa/dao/PagingAndSortingRepository.java     |    31 +
 .../catalog/jpa/dao/ProductRepository.java      |    22 +
 .../log4j/catalog/jpa/dao/package-info.java     |    19 +
 .../exception/InvalidEnvironmentException.java  |    41 +
 .../jpa/exception/InvalidSiteException.java     |    41 +
 .../log4j/catalog/jpa/model/AttributeModel.java |   323 +
 .../log4j/catalog/jpa/model/CategoryModel.java  |   168 +
 .../catalog/jpa/model/ConstraintModel.java      |    85 +
 .../catalog/jpa/model/EventAttributeModel.java  |   119 +
 .../log4j/catalog/jpa/model/EventModel.java     |   232 +
 .../log4j/catalog/jpa/model/ProductModel.java   |   152 +
 .../log4j/catalog/jpa/model/package-info.java   |    19 +
 .../logging/log4j/catalog/jpa/package-info.java |    19 +
 .../AbstractPagingAndSortingService.java        |    44 +
 .../catalog/jpa/service/AttributeService.java   |    33 +
 .../jpa/service/AttributeServiceImpl.java       |    67 +
 .../catalog/jpa/service/CatalogServiceImpl.java |   121 +
 .../catalog/jpa/service/CategoryService.java    |    33 +
 .../jpa/service/CategoryServiceImpl.java        |    68 +
 .../jpa/service/ConfigurationService.java       |    31 +
 .../catalog/jpa/service/ConstraintService.java  |    33 +
 .../jpa/service/ConstraintServiceImpl.java      |    67 +
 .../log4j/catalog/jpa/service/EventService.java |    35 +
 .../catalog/jpa/service/EventServiceImpl.java   |    80 +
 .../catalog/jpa/service/ProductService.java     |    30 +
 .../catalog/jpa/service/ProductServiceImpl.java |    68 +
 .../src/main/resources/sql/schema.sql           |   121 +
 .../logging/log4j/catalog/jpa/CatalogTest.java  |   203 +
 .../src/test/resources/log4j2.xml               |    45 +
 .../src/test/resources/sql/afterTestRun.sql     |    24 +
 .../src/test/resources/sql/beforeTestRun.sql    |    58 +
 log4j-catalog/log4j-catalog-war/pom.xml         |   182 +
 .../catalog/config/JsonObjectMapperFactory.java |   150 +
 .../log4j/catalog/config/SwaggerConfig.java     |    63 +
 .../log4j/catalog/config/WebAppInitializer.java |    44 +
 .../log4j/catalog/config/WebMvcAppContext.java  |   312 +
 .../catalog/controller/AttributeController.java |   183 +
 .../catalog/controller/CatalogController.java   |   399 +
 .../catalog/controller/CategoryController.java  |   130 +
 .../controller/ConstraintController.java        |    86 +
 .../catalog/controller/EventController.java     |   158 +
 .../catalog/controller/ProductController.java   |   130 +
 .../RestResponseEntityExceptionHandler.java     |    55 +
 .../RequestContextHeaderInterceptor.java        |    41 +
 .../security/LocalAuthorizationInterceptor.java |    54 +
 .../catalog/service/CatalogInitializer.java     |    99 +
 .../CatalogService/application.properties       |     2 +
 .../resources/CatalogService/lab.properties     |     2 +
 .../src/main/resources/log4j2.xml               |    43 +
 .../webapp/WEB-INF/templates/attributes.html    |    28 +
 .../webapp/WEB-INF/templates/categories.html    |    27 +
 .../main/webapp/WEB-INF/templates/events.html   |    28 +
 .../main/webapp/WEB-INF/templates/products.html |    27 +
 .../main/webapp/WEB-INF/templates/template.html |    25 +
 .../src/main/webapp/css/app.css                 |   154 +
 .../src/main/webapp/images/attributes.png       |   Bin 0 -> 1981 bytes
 .../src/main/webapp/images/constraint.png       |   Bin 0 -> 2586 bytes
 .../log4j-catalog-war/src/main/webapp/js/app.js |    43 +
 .../src/main/webapp/js/attributes.js            |   348 +
 .../src/main/webapp/js/categories.js            |   241 +
 .../src/main/webapp/js/events.js                |   253 +
 .../src/main/webapp/js/jquery-1.12.4.min.js     |     5 +
 .../src/main/webapp/js/jquery-2.2.4.min.js      |     4 +
 .../src/main/webapp/js/jquery-3.2.1.min.js      |     4 +
 .../main/webapp/js/jquery-ui-1.12.1/AUTHORS.txt |   333 +
 .../main/webapp/js/jquery-ui-1.12.1/LICENSE.txt |    43 +
 .../jquery-ui-1.12.1/external/jquery/jquery.js  | 11008 ++++++++++
 .../images/ui-icons_444444_256x240.png          |   Bin 0 -> 7006 bytes
 .../images/ui-icons_555555_256x240.png          |   Bin 0 -> 7074 bytes
 .../images/ui-icons_777620_256x240.png          |   Bin 0 -> 4676 bytes
 .../images/ui-icons_777777_256x240.png          |   Bin 0 -> 7013 bytes
 .../images/ui-icons_cc0000_256x240.png          |   Bin 0 -> 4632 bytes
 .../images/ui-icons_ffffff_256x240.png          |   Bin 0 -> 6313 bytes
 .../main/webapp/js/jquery-ui-1.12.1/index.html  |   559 +
 .../webapp/js/jquery-ui-1.12.1/jquery-ui.css    |  1312 ++
 .../webapp/js/jquery-ui-1.12.1/jquery-ui.js     | 18706 +++++++++++++++++
 .../js/jquery-ui-1.12.1/jquery-ui.min.css       |     7 +
 .../webapp/js/jquery-ui-1.12.1/jquery-ui.min.js |    13 +
 .../js/jquery-ui-1.12.1/jquery-ui.structure.css |   886 +
 .../jquery-ui.structure.min.css                 |     5 +
 .../js/jquery-ui-1.12.1/jquery-ui.theme.css     |   443 +
 .../js/jquery-ui-1.12.1/jquery-ui.theme.min.css |     5 +
 .../webapp/js/jquery-ui-1.12.1/package.json     |    74 +
 .../jquery.jtable.aspnetpagemethods.js          |   150 +
 .../jquery.jtable.aspnetpagemethods.min.js      |    27 +
 .../webapp/js/jtable.2.4.0/external/json2.js    |   486 +
 .../js/jtable.2.4.0/external/json2.min.js       |     8 +
 .../webapp/js/jtable.2.4.0/jquery.jtable.js     |  5021 +++++
 .../webapp/js/jtable.2.4.0/jquery.jtable.min.js |   157 +
 .../localization/jquery.jtable.bd.js            |    30 +
 .../localization/jquery.jtable.ca.js            |    30 +
 .../localization/jquery.jtable.cz.js            |    30 +
 .../localization/jquery.jtable.de.js            |    30 +
 .../localization/jquery.jtable.es.js            |    30 +
 .../localization/jquery.jtable.fa.js            |    30 +
 .../localization/jquery.jtable.fr.js            |    30 +
 .../localization/jquery.jtable.hr.js            |    30 +
 .../localization/jquery.jtable.hu.js            |    30 +
 .../localization/jquery.jtable.id.js            |    31 +
 .../localization/jquery.jtable.it.js            |    30 +
 .../localization/jquery.jtable.lt.js            |    30 +
 .../localization/jquery.jtable.nl-NL.js         |    30 +
 .../localization/jquery.jtable.no.js            |    30 +
 .../localization/jquery.jtable.pl.js            |    30 +
 .../localization/jquery.jtable.pt-BR.js         |    30 +
 .../localization/jquery.jtable.pt-PT.js         |    29 +
 .../localization/jquery.jtable.ro.js            |    30 +
 .../localization/jquery.jtable.ru.js            |    31 +
 .../localization/jquery.jtable.se.js            |    30 +
 .../localization/jquery.jtable.tr.js            |    30 +
 .../localization/jquery.jtable.vi.js            |    28 +
 .../localization/jquery.jtable.zh-CN.js         |    30 +
 .../js/jtable.2.4.0/themes/basic/close.png      |   Bin 0 -> 3350 bytes
 .../js/jtable.2.4.0/themes/basic/column-asc.png |   Bin 0 -> 362 bytes
 .../jtable.2.4.0/themes/basic/column-desc.png   |   Bin 0 -> 349 bytes
 .../themes/basic/column-sortable.png            |   Bin 0 -> 347 bytes
 .../js/jtable.2.4.0/themes/basic/delete.png     |   Bin 0 -> 150 bytes
 .../js/jtable.2.4.0/themes/basic/edit.png       |   Bin 0 -> 590 bytes
 .../jtable.2.4.0/themes/basic/jtable_basic.css  |   282 +
 .../jtable.2.4.0/themes/basic/jtable_basic.less |    83 +
 .../themes/basic/jtable_basic.min.css           |     1 +
 .../js/jtable.2.4.0/themes/jqueryui/add.png     |   Bin 0 -> 482 bytes
 .../jtable.2.4.0/themes/jqueryui/bg-thead.png   |   Bin 0 -> 2811 bytes
 .../js/jtable.2.4.0/themes/jqueryui/close.png   |   Bin 0 -> 1217 bytes
 .../jtable.2.4.0/themes/jqueryui/column-asc.png |   Bin 0 -> 362 bytes
 .../themes/jqueryui/column-desc.png             |   Bin 0 -> 349 bytes
 .../themes/jqueryui/column-sortable.png         |   Bin 0 -> 347 bytes
 .../js/jtable.2.4.0/themes/jqueryui/delete.png  |   Bin 0 -> 150 bytes
 .../js/jtable.2.4.0/themes/jqueryui/edit.png    |   Bin 0 -> 590 bytes
 .../themes/jqueryui/jtable_jqueryui.css         |   398 +
 .../themes/jqueryui/jtable_jqueryui.less        |   296 +
 .../themes/jqueryui/jtable_jqueryui.min.css     |     1 +
 .../js/jtable.2.4.0/themes/jqueryui/loading.gif |   Bin 0 -> 723 bytes
 .../jtable.2.4.0/themes/jtable_theme_base.less  |   524 +
 .../js/jtable.2.4.0/themes/lightcolor/add.png   |   Bin 0 -> 482 bytes
 .../jtable.2.4.0/themes/lightcolor/bg-thead.png |   Bin 0 -> 2811 bytes
 .../themes/lightcolor/blue/jtable.css           |   521 +
 .../themes/lightcolor/blue/jtable.less          |    90 +
 .../themes/lightcolor/blue/jtable.min.css       |     1 +
 .../themes/lightcolor/blue/loading.gif          |   Bin 0 -> 723 bytes
 .../js/jtable.2.4.0/themes/lightcolor/close.png |   Bin 0 -> 1217 bytes
 .../themes/lightcolor/column-asc.png            |   Bin 0 -> 362 bytes
 .../themes/lightcolor/column-desc.png           |   Bin 0 -> 349 bytes
 .../themes/lightcolor/column-sortable.png       |   Bin 0 -> 347 bytes
 .../jtable.2.4.0/themes/lightcolor/delete.png   |   Bin 0 -> 150 bytes
 .../js/jtable.2.4.0/themes/lightcolor/edit.png  |   Bin 0 -> 590 bytes
 .../themes/lightcolor/gray/jtable.css           |   521 +
 .../themes/lightcolor/gray/jtable.less          |    90 +
 .../themes/lightcolor/gray/jtable.min.css       |     1 +
 .../themes/lightcolor/gray/loading.gif          |   Bin 0 -> 723 bytes
 .../themes/lightcolor/green/jtable.css          |   521 +
 .../themes/lightcolor/green/jtable.less         |    90 +
 .../themes/lightcolor/green/jtable.min.css      |     1 +
 .../themes/lightcolor/green/loading.gif         |   Bin 0 -> 723 bytes
 .../lightcolor/jtable_lightcolor_base.less      |   329 +
 .../themes/lightcolor/orange/jtable.css         |   521 +
 .../themes/lightcolor/orange/jtable.less        |    90 +
 .../themes/lightcolor/orange/jtable.min.css     |     1 +
 .../themes/lightcolor/orange/loading.gif        |   Bin 0 -> 723 bytes
 .../themes/lightcolor/red/jtable.css            |   521 +
 .../themes/lightcolor/red/jtable.less           |    90 +
 .../themes/lightcolor/red/jtable.min.css        |     1 +
 .../themes/lightcolor/red/loading.gif           |   Bin 0 -> 723 bytes
 .../webapp/js/jtable.2.4.0/themes/metro/add.png |   Bin 0 -> 482 bytes
 .../jtable.2.4.0/themes/metro/blue/jtable.css   |   495 +
 .../jtable.2.4.0/themes/metro/blue/jtable.less  |    11 +
 .../themes/metro/blue/jtable.min.css            |     1 +
 .../jtable.2.4.0/themes/metro/blue/loading.gif  |   Bin 0 -> 404 bytes
 .../jtable.2.4.0/themes/metro/brown/jtable.css  |   495 +
 .../jtable.2.4.0/themes/metro/brown/jtable.less |    11 +
 .../themes/metro/brown/jtable.min.css           |     1 +
 .../jtable.2.4.0/themes/metro/brown/loading.gif |   Bin 0 -> 404 bytes
 .../js/jtable.2.4.0/themes/metro/close.png      |   Bin 0 -> 3350 bytes
 .../js/jtable.2.4.0/themes/metro/column-asc.png |   Bin 0 -> 320 bytes
 .../jtable.2.4.0/themes/metro/column-desc.png   |   Bin 0 -> 311 bytes
 .../themes/metro/column-sortable.png            |   Bin 0 -> 314 bytes
 .../themes/metro/crimson/jtable.css             |   495 +
 .../themes/metro/crimson/jtable.less            |    11 +
 .../themes/metro/crimson/jtable.min.css         |     1 +
 .../themes/metro/crimson/loading.gif            |   Bin 0 -> 404 bytes
 .../themes/metro/darkgray/jtable.css            |   495 +
 .../themes/metro/darkgray/jtable.less           |    11 +
 .../themes/metro/darkgray/jtable.min.css        |     1 +
 .../themes/metro/darkgray/loading.gif           |   Bin 0 -> 404 bytes
 .../themes/metro/darkorange/jtable.css          |   495 +
 .../themes/metro/darkorange/jtable.less         |    11 +
 .../themes/metro/darkorange/jtable.min.css      |     1 +
 .../themes/metro/darkorange/loading.gif         |   Bin 0 -> 404 bytes
 .../js/jtable.2.4.0/themes/metro/delete.png     |   Bin 0 -> 3167 bytes
 .../js/jtable.2.4.0/themes/metro/edit.png       |   Bin 0 -> 3359 bytes
 .../jtable.2.4.0/themes/metro/green/jtable.css  |   495 +
 .../jtable.2.4.0/themes/metro/green/jtable.less |    11 +
 .../themes/metro/green/jtable.min.css           |     1 +
 .../jtable.2.4.0/themes/metro/green/loading.gif |   Bin 0 -> 404 bytes
 .../themes/metro/jtable_metro_base.css          |    48 +
 .../themes/metro/jtable_metro_base.less         |   439 +
 .../themes/metro/jtable_metro_base.min.css      |     1 +
 .../themes/metro/lightgray/jtable.css           |   495 +
 .../themes/metro/lightgray/jtable.less          |    11 +
 .../themes/metro/lightgray/jtable.min.css       |     1 +
 .../themes/metro/lightgray/loading.gif          |   Bin 0 -> 404 bytes
 .../jtable.2.4.0/themes/metro/pink/jtable.css   |   495 +
 .../jtable.2.4.0/themes/metro/pink/jtable.less  |    11 +
 .../themes/metro/pink/jtable.min.css            |     1 +
 .../jtable.2.4.0/themes/metro/pink/loading.gif  |   Bin 0 -> 404 bytes
 .../jtable.2.4.0/themes/metro/purple/jtable.css |   495 +
 .../themes/metro/purple/jtable.less             |    11 +
 .../themes/metro/purple/jtable.min.css          |     1 +
 .../themes/metro/purple/loading.gif             |   Bin 0 -> 404 bytes
 .../js/jtable.2.4.0/themes/metro/red/jtable.css |   495 +
 .../jtable.2.4.0/themes/metro/red/jtable.less   |    11 +
 .../themes/metro/red/jtable.min.css             |     1 +
 .../jtable.2.4.0/themes/metro/red/loading.gif   |   Bin 0 -> 404 bytes
 .../src/main/webapp/js/products.js              |   241 +
 log4j-catalog/pom.xml                           |    36 +
 pom.xml                                         |  1314 ++
 363 files changed, 69216 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/NOTICE.txt
----------------------------------------------------------------------
diff --git a/NOTICE.txt b/NOTICE.txt
index 3b3bcf3..a655af0 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -1,5 +1,6 @@
-Apache Log4j
-Copyright 2016 Apache Software Foundation
+Apache Log4j Audit
+Copyright 2017 Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
+

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/RELEASE-NOTES.md
----------------------------------------------------------------------
diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
new file mode 100644
index 0000000..af0c9e1
--- /dev/null
+++ b/RELEASE-NOTES.md
@@ -0,0 +1,17 @@
+# Apache Log4j Audit 1.0.0 Release Notes
+
+This is the initial release of Log4j Audit. 
+
+## GA Release 1.0.0
+
+Changes in this version include:
+
+
+---
+
+Apache Log4j Audit 1.0.0 requires a minimum of Java 8 to build and run. 
+
+For complete information on Apache Log4j Audit, including instructions on how 
to submit bug
+reports, patches, or suggestions for improvement, see the Apache Apache Log4j 
Audit website:
+
+https://logging.apache.org/log4j-audit/
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit-distribution/pom.xml
----------------------------------------------------------------------
diff --git a/log4j-audit-distribution/pom.xml b/log4j-audit-distribution/pom.xml
new file mode 100644
index 0000000..38a9e80
--- /dev/null
+++ b/log4j-audit-distribution/pom.xml
@@ -0,0 +1,273 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";>
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.logging.log4j</groupId>
+    <artifactId>log4j-audit</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <relativePath>../</relativePath>
+  </parent>
+  <artifactId>log4j-audit-distribution</artifactId>
+  <packaging>pom</packaging>
+  <name>Log4j Audit Distribution</name>
+  <description>The Apache Log4j Audit distribution archives.</description>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-audit-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-audit-api</artifactId>
+      <version>${project.version}</version>
+      <classifier>sources</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-audit-api</artifactId>
+      <version>${project.version}</version>
+      <classifier>javadoc</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-audit-maven-plugin</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-audit-maven-plugin</artifactId>
+      <version>${project.version}</version>
+      <classifier>sources</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-audit-maven-plugin</artifactId>
+      <version>${project.version}</version>
+      <classifier>javadoc</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-audit-war</artifactId>
+      <version>${project.version}</version>
+      <type>war</type>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-audit-war</artifactId>
+      <version>${project.version}</version>
+      <classifier>sources</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-audit-war</artifactId>
+      <version>${project.version}</version>
+      <classifier>javadoc</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-catalog-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-catalog-api</artifactId>
+      <version>${project.version}</version>
+      <classifier>sources</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-catalog-api</artifactId>
+      <version>${project.version}</version>
+      <classifier>javadoc</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-catalog-client</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-catalog-client</artifactId>
+      <version>${project.version}</version>
+      <classifier>sources</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-catalog-client</artifactId>
+      <version>${project.version}</version>
+      <classifier>javadoc</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-catalog-git</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-catalog-git</artifactId>
+      <version>${project.version}</version>
+      <classifier>sources</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-catalog-git</artifactId>
+      <version>${project.version}</version>
+      <classifier>javadoc</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-catalog-impl</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-catalog-impl</artifactId>
+      <version>${project.version}</version>
+      <classifier>sources</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-catalog-impl</artifactId>
+      <version>${project.version}</version>
+      <classifier>javadoc</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-catalog-jpa</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-catalog-jpa</artifactId>
+      <version>${project.version}</version>
+      <classifier>sources</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-catalog-jpa</artifactId>
+      <version>${project.version}</version>
+      <classifier>javadoc</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-catalog-redis</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-catalog-redis</artifactId>
+      <version>${project.version}</version>
+      <classifier>sources</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-catalog-redis</artifactId>
+      <version>${project.version}</version>
+      <classifier>javadoc</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-catalog-war</artifactId>
+      <type>war</type>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-catalog-war</artifactId>
+      <version>${project.version}</version>
+      <classifier>sources</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-catalog-war</artifactId>
+      <version>${project.version}</version>
+      <classifier>javadoc</classifier>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <executions>
+
+          <execution>
+            <id>log4j2-source-release-assembly</id>
+            <phase>package</phase>
+            <goals>
+              <goal>single</goal>
+            </goals>
+            <configuration>
+              <finalName>apache-log4j-audit-${project.version}</finalName>
+              <descriptors>
+                <descriptor>src/assembly/src.xml</descriptor>
+              </descriptors>
+              <tarLongFileMode>gnu</tarLongFileMode>
+            </configuration>
+          </execution>
+          <execution>
+            <id>binary</id>
+            <configuration>
+              <finalName>apache-log4j-audit-${project.version}</finalName>
+              <descriptors>
+                <descriptor>src/assembly/bin.xml</descriptor>
+              </descriptors>
+              <tarLongFileMode>gnu</tarLongFileMode>
+            </configuration>
+            <goals>
+              <goal>single</goal>
+            </goals>
+            <phase>package</phase>
+          </execution>
+          <!-- <execution>
+            <id>osgi-binary</id>
+            <configuration>
+              <finalName>apache-log4j-${project.version}</finalName>
+              <descriptors>
+                <descriptor>src/assembly/osgi-bin.xml</descriptor>
+              </descriptors>
+              <tarLongFileMode>gnu</tarLongFileMode>
+            </configuration>
+            <goals>
+              <goal>single</goal>
+            </goals>
+            <phase>package</phase>
+          </execution> -->
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-site-plugin</artifactId>
+        <version>3.0</version>
+        <configuration>
+          <skip>true</skip>
+          <skipDeploy>true</skipDeploy>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-deploy-plugin</artifactId>
+        <version>2.8.2</version>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit-distribution/src/assembly/bin.xml
----------------------------------------------------------------------
diff --git a/log4j-audit-distribution/src/assembly/bin.xml 
b/log4j-audit-distribution/src/assembly/bin.xml
new file mode 100644
index 0000000..6cee98e
--- /dev/null
+++ b/log4j-audit-distribution/src/assembly/bin.xml
@@ -0,0 +1,59 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you 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.
+-->
+<assembly>
+    <id>bin</id>
+    <formats>
+        <format>tar.gz</format>
+        <format>zip</format>
+    </formats>
+    <baseDirectory>apache-log4j-audit-${project.version}-bin</baseDirectory>
+    <includeSiteDirectory>false</includeSiteDirectory>
+    <moduleSets>
+        <moduleSet>
+            <useAllReactorProjects>true</useAllReactorProjects>
+        </moduleSet>
+    </moduleSets>
+    <dependencySets>
+        <dependencySet>
+            <includes>
+                <include>org.apache.logging.log4j:log4j-*</include>
+            </includes>
+            <outputDirectory></outputDirectory>
+            <unpack>false</unpack>
+        </dependencySet>
+    </dependencySets>
+
+    <fileSets>
+        <fileSet>
+            <directory>..</directory>
+            <includes>
+                <include>LICENSE.txt</include>
+                <include>NOTICE.txt</include>
+            </includes>
+        </fileSet>
+    </fileSets>
+    <files>
+         <file>
+            <source>../RELEASE-NOTES.md</source>
+            <outputDirectory>.</outputDirectory>
+            <destName>RELEASE-NOTES.md</destName>
+        </file>
+    </files>
+</assembly>

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit-distribution/src/assembly/src.xml
----------------------------------------------------------------------
diff --git a/log4j-audit-distribution/src/assembly/src.xml 
b/log4j-audit-distribution/src/assembly/src.xml
new file mode 100644
index 0000000..b38a99d
--- /dev/null
+++ b/log4j-audit-distribution/src/assembly/src.xml
@@ -0,0 +1,81 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you 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.
+-->
+
+<assembly>
+  <id>src</id>
+  <formats>
+    <format>zip</format>
+    <format>tar.gz</format>
+  </formats>
+  <baseDirectory>apache-log4j-${project.version}-src</baseDirectory>
+  <fileSets>
+    <!-- main project directory structure -->
+    <fileSet>
+      <directory>..</directory>
+      <outputDirectory>/</outputDirectory>
+      <useDefaultExcludes>true</useDefaultExcludes>
+      <excludes>
+        <exclude>**/flume-og/**</exclude>
+        <!-- build output -->
+        
<exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/).*${project.build.directory}.*]</exclude>
+
+        <!-- NOTE: Most of the following excludes should not be required
+             if the standard release process is followed. This is because the
+             release plugin checks out project sources into a location like
+             target/checkout, then runs the build from there. The result is
+             a source-release archive that comes from a pretty clean directory
+             structure.
+
+             HOWEVER, if the release plugin is configured to run extra goals
+             or generate a project website, it's definitely possible that some
+             of these files will be present. So, it's safer to exclude them.
+        -->
+
+        <!-- IDEs -->
+        
<exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?maven-eclipse\.xml]</exclude>
+        
<exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.project]</exclude>
+        
<exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.classpath]</exclude>
+        
<exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?[^/]*\.iws]</exclude>
+        
<exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?[^/]*\.ipr]</exclude>
+        
<exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?[^/]*\.iml]</exclude>
+        
<exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.idea(/.*)?]</exclude>
+        
<exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.settings(/.*)?]</exclude>
+        
<exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?Vagrantfile(/.*)?]</exclude>
+        
<exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?Dockerfile(/.*)?]</exclude>
+        
<exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.externalToolBuilders(/.*)?]</exclude>
+        
<exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.deployables(/.*)?]</exclude>
+        
<exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.wtpmodules(/.*)?]</exclude>
+
+        <!-- misc -->
+        
<exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?cobertura\.ser]</exclude>
+        
<exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?doap_vfs\.rdf]</exclude>
+
+        <!-- release-plugin temp files -->
+        
<exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?pom\.xml\.releaseBackup]</exclude>
+        
<exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?release\.properties]</exclude>
+      </excludes>
+    </fileSet>
+    <!-- license, readme, etc. calculated at build time
+    <fileSet>
+      
<directory>${project.build.directory}/maven-shared-archive-resources/META-INF</directory>
+      <outputDirectory>/</outputDirectory>
+    </fileSet>  -->
+  </fileSets>
+</assembly>

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit/log4j-audit-api/pom.xml
----------------------------------------------------------------------
diff --git a/log4j-audit/log4j-audit-api/pom.xml 
b/log4j-audit/log4j-audit-api/pom.xml
new file mode 100644
index 0000000..f44407a
--- /dev/null
+++ b/log4j-audit/log4j-audit-api/pom.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements. See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";>
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.logging.log4j</groupId>
+    <artifactId>log4j-audit</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>log4j-audit-api</artifactId>
+  <packaging>jar</packaging>
+  <name>Log4j Audit API</name>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-catalog-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-databind</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-annotations</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.datatype</groupId>
+      <artifactId>jackson-datatype-jsr310</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>net.sf.jopt-simple</groupId>
+      <artifactId>jopt-simple</artifactId>
+    </dependency>
+    <!-- Test Dependencies -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-jcl</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-core</artifactId>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>javax.servlet-api</artifactId>
+      <version>3.0.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AbstractEventLogger.java
----------------------------------------------------------------------
diff --git 
a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AbstractEventLogger.java
 
b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AbstractEventLogger.java
new file mode 100644
index 0000000..858a55d
--- /dev/null
+++ 
b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AbstractEventLogger.java
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.logging.log4j.audit;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.audit.catalog.CatalogManager;
+import org.apache.logging.log4j.audit.exception.AuditException;
+import org.apache.logging.log4j.catalog.api.Attribute;
+import org.apache.logging.log4j.catalog.api.Constraint;
+import org.apache.logging.log4j.catalog.api.Event;
+import org.apache.logging.log4j.catalog.api.EventAttribute;
+import org.apache.logging.log4j.catalog.api.plugins.ConstraintPlugins;
+import org.apache.logging.log4j.message.StructuredDataMessage;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ */
+public abstract class AbstractEventLogger {
+
+    private static final Logger logger = 
LogManager.getLogger(AbstractEventLogger.class);
+
+    private static final int DEFAULT_MAX_LENGTH = 32;
+
+    private static ConstraintPlugins constraintPlugins = 
ConstraintPlugins.getInstance();
+
+    public CatalogManager catalogManager;
+
+    private static final AuditExceptionHandler DEFAULT_EXCEPTION_HANDLER = 
(message, ex) -> {
+        throw new AuditException("Error logging event " + 
message.getId().getName(), ex);
+    };
+
+    private static final AuditExceptionHandler NOOP_EXCEPTION_HANDLER = 
(message, ex) -> {
+    };
+
+    private AuditExceptionHandler defaultAuditExceptionHandler = 
DEFAULT_EXCEPTION_HANDLER;
+
+    private final int maxLength;
+
+    protected AbstractEventLogger() {
+        maxLength = DEFAULT_MAX_LENGTH;
+    }
+
+    protected AbstractEventLogger(int maxLength) {
+        this.maxLength = maxLength;
+    }
+
+    public void setCatalogManager(CatalogManager catalogManager) {
+        this.catalogManager = catalogManager;
+    }
+
+    public List<String> getAttributeNames(String eventId) {
+        return catalogManager.getAttributeNames(eventId);
+    }
+
+    public void setDefaultAuditExceptionHandler(AuditExceptionHandler 
auditExceptionHandler) {
+        defaultAuditExceptionHandler = auditExceptionHandler == null ? 
NOOP_EXCEPTION_HANDLER : auditExceptionHandler;
+    }
+
+    public void logEvent(String eventName, Map<String, String> attributes) {
+        Event event = catalogManager.getEvent(eventName);
+        if (event == null) {
+            throw new AuditException("Unable to locate definition of audit 
event " + eventName);
+        }
+        logEvent(eventName, attributes, event, defaultAuditExceptionHandler);
+    }
+
+    public void logEvent(String eventName, Map<String, String> attributes, 
AuditExceptionHandler exceptionHandler) {
+        Event event = catalogManager.getEvent(eventName);
+
+        if (event == null) {
+            throw new AuditException("Unable to locate definition of audit 
event " + eventName);
+        }
+        logEvent(eventName, attributes, event, exceptionHandler);
+    }
+
+    protected abstract void logEvent(StructuredDataMessage message);
+
+    private void logEvent(String eventName, Map<String, String> attributes, 
Event event,
+                          AuditExceptionHandler exceptionHandler) {
+        AuditMessage msg = new AuditMessage(eventName, maxLength);
+
+        StringBuilder missingAttributes = new StringBuilder();
+        StringBuilder errors = new StringBuilder();
+
+        for (EventAttribute eventAttribute : event.getAttributes()) {
+            Attribute attr = 
catalogManager.getAttribute(eventAttribute.getName());
+            if (!attr.isRequestContext() && (attr.isRequired() || 
eventAttribute.isRequired())) {
+                String name = attr.getName();
+                if (!attributes.containsKey(name)) {
+                    if (missingAttributes.length() > 0) {
+                        missingAttributes.append(", ");
+                    }
+                    missingAttributes.append(name);
+                } else {
+                    if (attr.getConstraints() != null && 
attr.getConstraints().size() > 0) {
+                        Constraint[] constraints = 
attr.getConstraints().toArray(new Constraint[attr.getConstraints().size()]);
+                        validateConstraints(false, constraints, name, 
attributes.get(name), errors);
+                    }
+                }
+            }
+        }
+        Map<String, Attribute> attributeMap = 
catalogManager.getAttributes(eventName);
+        for (String name : attributes.keySet()) {
+            if (!attributeMap.containsKey(name) && 
!name.equals("completionStatus")) {
+                if (errors.length() > 0) {
+                    errors.append("\n");
+                }
+                errors.append("Attribute ").append(name).append(" is not 
defined for ").append(eventName);
+            }
+        }
+        if (missingAttributes.length() > 0) {
+            if (errors.length() > 0) {
+                errors.append("\n");
+            }
+            errors.append("Event ").append(eventName).append(" is missing 
required attribute(s) ").append(missingAttributes.toString());
+        }
+        if (errors.length() > 0) {
+            throw new AuditException(errors.toString());
+        }
+        List<String> attributeNames = 
catalogManager.getAttributeNames(eventName);
+        StringBuilder buf = new StringBuilder();
+        for (String attribute : attributes.keySet()) {
+            if (!attributeNames.contains(attribute)) {
+                if (buf.length() > 0) {
+                    buf.append(", ");
+                }
+                buf.append(attribute);
+            }
+        }
+        if (buf.length() > 0) {
+            throw new AuditException("Event " + eventName + " contains invalid 
attribute(s) " + buf.toString());
+        }
+
+        List<String> reqCtxAttrs = 
catalogManager.getRequiredContextAttributes(eventName);
+
+        if (reqCtxAttrs != null) {
+            StringBuilder sb = new StringBuilder();
+            for (String attr : reqCtxAttrs) {
+                if (!ThreadContext.containsKey(attr)) {
+                    if (sb.length() > 0) {
+                        sb.append(", ");
+                    }
+                    sb.append(attr);
+                }
+            }
+            if (sb.length() > 0) {
+                throw new IllegalStateException("Event " + 
msg.getId().getName() +
+                        " is missing required RequestContext values for " + 
sb.toString());
+            }
+        }
+        Map<String, Attribute> reqCtxAttributes = 
catalogManager.getRequestContextAttributes();
+        for (Map.Entry<String, String> entry : 
ThreadContext.getImmutableContext().entrySet()) {
+            Attribute attribute = reqCtxAttributes.get(entry.getKey());
+            if (attribute == null) {
+                continue;
+            }
+            Set<Constraint> constraintList = attribute.getConstraints();
+            if (constraintList != null && constraintList.size() > 0) {
+                Constraint[] constraints =
+                        attribute.getConstraints().toArray(new 
Constraint[attribute.getConstraints().size()]);
+                validateConstraints(true, constraints, entry.getKey(), 
ThreadContext.get(entry.getKey()), errors);
+            }
+        }
+        if (errors.length() > 0) {
+            throw new AuditException("Event " + eventName + " has incorrect 
data in the Thread Context: " + errors.toString());
+        }
+        msg.putAll(attributes);
+        try {
+            logEvent(msg);
+        } catch (Throwable ex) {
+            if (exceptionHandler == null) {
+                defaultAuditExceptionHandler.handleException(msg, ex);
+            } else {
+                exceptionHandler.handleException(msg, ex);
+            }
+        }
+    }
+
+    private static void validateConstraints(boolean isRequestContext, 
Constraint[] constraints, String name,
+                                            String value, StringBuilder 
errors) {
+        for (Constraint constraint : constraints) {
+            constraintPlugins.validateConstraint(isRequestContext, 
constraint.getConstraintType().getName(), name, value,
+                    constraint.getValue(), errors);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/ActivityLogger.java
----------------------------------------------------------------------
diff --git 
a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/ActivityLogger.java
 
b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/ActivityLogger.java
new file mode 100644
index 0000000..5c1381f
--- /dev/null
+++ 
b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/ActivityLogger.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.logging.log4j.audit;
+
+import org.apache.logging.log4j.EventLogger;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.MarkerManager;
+import org.apache.logging.log4j.message.StructuredDataMessage;
+import org.apache.logging.log4j.spi.ExtendedLogger;
+
+/**
+ *
+ */
+public class ActivityLogger extends AbstractEventLogger {
+    private static final String NAME = "ActivityLogger";
+
+    private static final String FQCN = ActivityLogger.class.getName();
+    private static Marker EVENT_MARKER = 
MarkerManager.getMarker("Activity").addParents(EventLogger.EVENT_MARKER);
+    private static final ExtendedLogger LOGGER = 
LogManager.getContext(false).getLogger(NAME);
+
+    public ActivityLogger() {
+        super();
+    }
+
+    public ActivityLogger(int maxLength) {
+        super(maxLength);
+    }
+
+    @Override
+    protected void logEvent(StructuredDataMessage message) {
+        LOGGER.logIfEnabled(FQCN, Level.OFF, EVENT_MARKER, message, null);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditEvent.java
----------------------------------------------------------------------
diff --git 
a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditEvent.java
 
b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditEvent.java
new file mode 100644
index 0000000..cad2ea0
--- /dev/null
+++ 
b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditEvent.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.logging.log4j.audit;
+
+/**
+ * Interface that is extended by generated classes.
+ */
+public interface AuditEvent {
+
+    /**
+     * Log the event.
+     */
+    void logEvent();
+
+    /**
+     * Set the exception handler to use. The default exception handler will 
throw an AuditException wrapping the
+     * exception that occurred. If null is passed in then the exception will 
be ignored.
+     * @param exceptionHandler The exception handler.
+     */
+    void setAuditExceptionHandler(AuditExceptionHandler exceptionHandler);
+
+    /**
+     * Added to the event after the operation has completed. Identifies 
whether it was successful or not.
+     * @param status The completion status.
+     */
+    void setCompletionStatus(String status);
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditExceptionHandler.java
----------------------------------------------------------------------
diff --git 
a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditExceptionHandler.java
 
b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditExceptionHandler.java
new file mode 100644
index 0000000..adf6376
--- /dev/null
+++ 
b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditExceptionHandler.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.logging.log4j.audit;
+
+import org.apache.logging.log4j.message.StructuredDataMessage;
+
+/**
+ * Handles any exceptions that may occur while logging the audit event.
+ */
+public interface AuditExceptionHandler {
+
+    /**
+     * Handles Exceptions that occur while audit logging. If a 
RuntimeException is thrown it will percolate
+     * back to the application.
+     * @param message The message being loggeed.
+     * @param ex The Throwable.
+     */
+    void handleException(StructuredDataMessage message, Throwable ex);
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditLogger.java
----------------------------------------------------------------------
diff --git 
a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditLogger.java
 
b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditLogger.java
new file mode 100644
index 0000000..d521399
--- /dev/null
+++ 
b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditLogger.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.logging.log4j.audit;
+
+import org.apache.logging.log4j.EventLogger;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.MarkerManager;
+import org.apache.logging.log4j.message.StructuredDataMessage;
+import org.apache.logging.log4j.spi.ExtendedLogger;
+
+/**
+ *
+ */
+public class AuditLogger extends AbstractEventLogger {
+
+    private static final String NAME = "AuditLogger";
+
+    private static final String FQCN = AuditLogger.class.getName();
+    private static Marker EVENT_MARKER = 
MarkerManager.getMarker("Audit").addParents(EventLogger.EVENT_MARKER);
+    private static final ExtendedLogger LOGGER = 
LogManager.getContext(false).getLogger(NAME);
+
+    public AuditLogger() {
+        super();
+    }
+
+    public AuditLogger(int maxLength) {
+        super(maxLength);
+    }
+
+    @Override
+    protected void logEvent(StructuredDataMessage message) {
+        LOGGER.logIfEnabled(FQCN, Level.OFF, EVENT_MARKER, message, null);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditMessage.java
----------------------------------------------------------------------
diff --git 
a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditMessage.java
 
b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditMessage.java
new file mode 100644
index 0000000..35b15a5
--- /dev/null
+++ 
b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditMessage.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.logging.log4j.audit;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.logging.log4j.message.StructuredDataId;
+import org.apache.logging.log4j.message.StructuredDataMessage;
+
+/**
+ *
+ */
+public class AuditMessage extends StructuredDataMessage {
+
+    private static final int MAX_LENGTH = 32;
+
+    private Map<String, StructuredDataMessage> extraContent = new HashMap<>();
+
+    public AuditMessage(String eventName) {
+         this(eventName, MAX_LENGTH);
+    }
+
+    public AuditMessage(String eventName, int maxLength) {
+        // Use this with Log4j 2.9
+     //   super(new AuditId(eventName, MAX_LENGTH), null, "Audit", maxLength);
+        super(new AuditId(eventName, maxLength), null, "Audit");
+    }
+
+    public void addContent(String name, StructuredDataMessage message) {
+        extraContent.put(name, message);
+    }
+
+    private static class AuditId extends StructuredDataId {
+
+        AuditId(String eventName, int maxLength) {
+            // Use this with Log4j 2.9
+            // super(eventName, maxLength);
+            super(eventName, null, null);
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/LogEventFactory.java
----------------------------------------------------------------------
diff --git 
a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/LogEventFactory.java
 
b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/LogEventFactory.java
new file mode 100644
index 0000000..ef2cdf1
--- /dev/null
+++ 
b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/LogEventFactory.java
@@ -0,0 +1,385 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.logging.log4j.audit;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.EventLogger;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.MarkerManager;
+import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.audit.annotation.Constraint;
+import org.apache.logging.log4j.audit.annotation.Constraints;
+import org.apache.logging.log4j.audit.annotation.MaxLength;
+import org.apache.logging.log4j.audit.annotation.RequestContext;
+import org.apache.logging.log4j.audit.annotation.RequestContextConstraints;
+import org.apache.logging.log4j.audit.annotation.Required;
+import org.apache.logging.log4j.audit.exception.AuditException;
+import org.apache.logging.log4j.audit.util.NamingUtils;
+import 
org.apache.logging.log4j.catalog.api.exception.ConstraintValidationException;
+import org.apache.logging.log4j.catalog.api.plugins.ConstraintPlugins;
+import org.apache.logging.log4j.message.StructuredDataMessage;
+import org.apache.logging.log4j.spi.ExtendedLogger;
+
+import static 
org.apache.logging.log4j.catalog.api.util.StringUtils.appendNewline;
+
+/**
+ *
+ */
+public class LogEventFactory {
+
+    private static final Logger logger = 
LogManager.getLogger(LogEventFactory.class);
+    private static final String NAME = "AuditLogger";
+    private static final String FQCN = LogEventFactory.class.getName();
+    private static Marker EVENT_MARKER = 
MarkerManager.getMarker("Audit").addParents(EventLogger.EVENT_MARKER);
+    private static final ExtendedLogger LOGGER = 
LogManager.getContext(false).getLogger(NAME);
+    private static final int DEFAULT_MAX_LENGTH = 32;
+
+    private static final AuditExceptionHandler DEFAULT_HANDLER = (message, ex) 
-> {
+        throw new AuditException("Error logging event " + 
message.getId().getName(), ex);
+    };
+
+    private static final AuditExceptionHandler NOOP_EXCEPTION_HANDLER = 
(message, ex) -> {
+    };
+
+    private static AuditExceptionHandler defaultExceptionHandler = 
DEFAULT_HANDLER;
+
+    private static ConcurrentMap<Class<?>, List<Property>> classMap = new 
ConcurrentHashMap<>();
+
+    private static ConstraintPlugins constraintPlugins = 
ConstraintPlugins.getInstance();
+
+    public static void setDefaultHandler(AuditExceptionHandler 
exceptionHandler) {
+        defaultExceptionHandler = (exceptionHandler == null) ? 
NOOP_EXCEPTION_HANDLER : exceptionHandler;
+    }
+
+    @SuppressWarnings("unchecked")
+       public static <T> T getEvent(Class<T> intrface) {
+
+               Class<?>[] interfaces = new Class<?>[] { intrface };
+
+        String eventId = NamingUtils.lowerFirst(intrface.getSimpleName());
+        int msgLength = intrface.getAnnotation(MaxLength.class).value();
+        AuditMessage msg = new AuditMessage(eventId, msgLength);
+               AuditEvent audit = (AuditEvent) Proxy.newProxyInstance(intrface
+                               .getClassLoader(), interfaces, new 
AuditProxy(msg, intrface));
+
+               return (T) audit;
+       }
+
+    public static void logEvent(Class<?> intrface, Map<String, String> 
properties) {
+           logEvent(intrface, properties, DEFAULT_HANDLER);
+    }
+
+    public static void logEvent(Class<?> intrface, Map<String, String> 
properties, AuditExceptionHandler handler) {
+        StringBuilder errors = new StringBuilder();
+        validateContextConstraints(intrface, errors);
+
+        String eventId = NamingUtils.lowerFirst(intrface.getSimpleName());
+        int maxLength = intrface.getAnnotation(MaxLength.class).value();
+        AuditMessage msg = new AuditMessage(eventId, maxLength);
+        List<Property> props = getProperties(intrface);
+        Map<String, Property> propertyMap = new HashMap<>();
+
+        for (Property property : props ) {
+            propertyMap.put(property.name, property);
+            if (property.isRequired && !properties.containsKey(property.name)) 
{
+                if (errors.length() > 0) {
+                    errors.append("\n");
+                }
+                errors.append("Required attribute 
").append(property.name).append(" is missing from ").append(eventId);
+            }
+            if (properties.containsKey(property.name)) {
+                validateConstraints(false, property.constraints, 
property.name, properties, errors);
+            }
+        }
+
+        for (Map.Entry<String, String> entry : properties.entrySet()) {
+            if (!propertyMap.containsKey(entry.getKey())) {
+                if (errors.length() > 0) {
+                    errors.append("Attribute 
").append(entry.getKey()).append(" is not defined for ").append(eventId);
+                }
+            }
+        }
+
+        if (errors.length() > 0) {
+            throw new ConstraintValidationException(errors.toString());
+        }
+        for (Map.Entry<String, String> entry : properties.entrySet()) {
+            msg.put(entry.getKey(), entry.getValue());
+        }
+        logEvent(msg, handler);
+    }
+
+    public static void logEvent(AuditMessage msg, AuditExceptionHandler 
handler) {
+        try {
+            LOGGER.logIfEnabled(FQCN, Level.OFF, EVENT_MARKER, msg, null);
+        } catch (Throwable ex) {
+            if (handler == null) {
+                handler = defaultExceptionHandler;
+            }
+            handler.handleException(msg, ex);
+        }
+    }
+
+    public static List<String> getPropertyNames(String className) {
+        Class<?> intrface = getClass(className);
+        List<String> names;
+        if (intrface != null) {
+            List<Property> props = getProperties(intrface);
+            names = new ArrayList<>(props.size());
+            for (Property prop : props) {
+                names.add(prop.name);
+            }
+        } else {
+            names = new ArrayList<>();
+        }
+        return names;
+    }
+
+    private static List<Property> getProperties(Class<?> intrface) {
+        List<Property> props = classMap.get(intrface);
+        if (props != null) {
+            return props;
+        }
+        props = new ArrayList<>();
+        Method[] methods = intrface.getMethods();
+        boolean isCompletionStatus = false;
+        for (Method method : methods) {
+            if (method.getName().startsWith("set") && 
!method.getName().equals("setAuditExceptionHandler")) {
+                if (method.getName().equals("setCompletionStatus")) {
+                    isCompletionStatus = true;
+                }
+                String name = 
NamingUtils.lowerFirst(NamingUtils.getMethodShortName(method.getName()));
+                Annotation[] annotations = method.getDeclaredAnnotations();
+                List<Constraint> constraints = new ArrayList<>();
+                boolean isRequired = false;
+                for (Annotation annotation : annotations) {
+                    if (annotation instanceof Constraint) {
+                        constraints.add((Constraint) annotation);
+                    }
+                    if (annotation instanceof Required) {
+                        isRequired = true;
+                    }
+                }
+                props.add(new Property(name, isRequired, constraints));
+            }
+        }
+        if (!isCompletionStatus) {
+            props.add(new Property("completionStatus", false, new 
ArrayList<>()));
+        }
+
+        classMap.putIfAbsent(intrface, props);
+        return classMap.get(intrface);
+    }
+
+    private static Class<?> getClass(String className) {
+        try {
+            Class<?> intrface = Class.forName(className);
+            if (AuditEvent.class.isAssignableFrom(intrface)) {
+                return intrface;
+            }
+            logger.error(className + " is not an AuditEvent");
+        } catch (ClassNotFoundException cnfe) {
+            logger.error("Unable to locate class {}", className);
+        }
+        return null;
+    }
+
+       private static class AuditProxy implements InvocationHandler {
+
+               private final AuditMessage msg;
+               private final Class<?> intrface;
+        private AuditExceptionHandler auditExceptionHandler = DEFAULT_HANDLER;
+
+               AuditProxy(AuditMessage msg, Class<?> intrface) {
+                       this.msg = msg;
+                       this.intrface = intrface;
+               }
+
+        public AuditMessage getMessage() {
+            return msg;
+        }
+
+               @Override
+        @SuppressWarnings("unchecked")
+               public Object invoke(Object o, Method method, Object[] objects)
+                               throws Throwable {
+                       if (method.getName().equals("logEvent")) {
+
+                               StringBuilder errors = new StringBuilder();
+                               validateContextConstraints(intrface, errors);
+
+                StringBuilder missing = new StringBuilder();
+                               Method[] methods = intrface.getMethods();
+
+                               for (Method _method : methods) {
+                                       String name = 
NamingUtils.lowerFirst(NamingUtils.getMethodShortName(_method.getName()));
+
+                                       Annotation[] annotations = 
_method.getDeclaredAnnotations();
+                                       for (Annotation annotation : 
annotations) {
+                        if (annotation instanceof Required && msg.get(name) == 
null) {
+                            if (missing.length() > 0) {
+                                missing.append(", ");
+                            }
+                            missing.append(name);
+                        }
+                                       }
+                               }
+                               if (errors.length() > 0) {
+                                   if (missing.length() > 0) {
+                                       errors.append("\n");
+                                       errors.append("Required attributes are 
missing: ");
+                                       errors.append(missing.toString());
+                    }
+                } else if (missing.length() > 0) {
+                    errors.append("Required attributes are missing: ");
+                                   errors = missing;
+                }
+
+                               if (errors.length() > 0) {
+                                       throw new 
ConstraintValidationException("Event " + msg.getId().getName() +
+                                                       " has errors :\n" + 
errors.toString());
+                               }
+
+                logEvent(msg, auditExceptionHandler);
+                       }
+            if (method.getName().equals("setCompletionStatus")) {
+                String name = 
NamingUtils.lowerFirst(NamingUtils.getMethodShortName(method.getName()));
+                if (objects == null || objects[0] == null) {
+                    throw new IllegalArgumentException("Missing completion 
status");
+                }
+                msg.put(name, objects[0].toString());
+            }
+            if (method.getName().equals("setAuditExceptionHandler")) {
+                           if (objects == null || objects[0] == null) {
+                    auditExceptionHandler = NOOP_EXCEPTION_HANDLER;
+                } else if (objects[0] instanceof AuditExceptionHandler) {
+                               auditExceptionHandler = (AuditExceptionHandler) 
objects[0];
+                } else {
+                               throw new IllegalArgumentException(objects[0] + 
" is not an " + AuditExceptionHandler.class.getName());
+                }
+            }
+                       if (method.getName().startsWith("set")) {
+                               String name = 
NamingUtils.lowerFirst(NamingUtils.getMethodShortName(method.getName()));
+                               if (objects == null || objects[0] == null) {
+                                   throw new IllegalArgumentException("No 
value to be set for " + name);
+                }
+
+                Annotation[] annotations = method.getDeclaredAnnotations();
+                               Class<?> returnType = method.getReturnType();
+                               StringBuilder errors = new StringBuilder();
+                for (Annotation annotation : annotations) {
+
+                    if (annotation instanceof Constraints) {
+                        Constraints constraints = (Constraints) annotation;
+                        validateConstraints(false, constraints.value(), name, 
objects[0].toString(),
+                                errors);
+                    } else if (annotation instanceof Constraint) {
+                        Constraint constraint = (Constraint) annotation;
+                        constraintPlugins.validateConstraint(false, 
constraint.constraintType(),
+                                name, objects[0].toString(), 
constraint.constraintValue(), errors);
+                    }
+                }
+                if (errors.length() > 0) {
+                    throw new ConstraintValidationException(errors.toString());
+                }
+                String result;
+                if (objects[0] instanceof List) {
+                    result = StringUtils.join(objects, ", ");
+                } else if (objects[0] instanceof Map) {
+                    StructuredDataMessage extra = new 
StructuredDataMessage(name, null, null);
+                    extra.putAll((Map)objects[0]);
+                    msg.addContent(name, extra);
+                    return null;
+                } else {
+                    result = objects[0].toString();
+                }
+
+                               msg.put(name, result);
+                       }
+
+                       return null;
+               }
+    }
+
+    private static void validateConstraints(boolean isRequestContext, 
Constraint[] constraints, String name,
+                                            Map<String, String> properties, 
StringBuilder errors) {
+        String value = isRequestContext ? ThreadContext.get(name) : 
properties.get(name);
+        validateConstraints(isRequestContext, constraints, name, value, 
errors);
+    }
+
+    private static void validateConstraints(boolean isRequestContext, 
Constraint[] constraints, String name,
+                                            String value, StringBuilder 
errors) {
+        for (Constraint constraint : constraints) {
+            constraintPlugins.validateConstraint(isRequestContext, 
constraint.constraintType(), name, value,
+                    constraint.constraintValue(), errors);
+        }
+    }
+
+    private static void validateContextConstraints(Class<?> intrface, 
StringBuilder buffer) {
+        RequestContextConstraints reqCtxConstraints = 
intrface.getAnnotation(RequestContextConstraints.class);
+        if (reqCtxConstraints != null) {
+            for (RequestContext ctx : reqCtxConstraints.value()) {
+                validateContextConstraint(ctx, buffer);
+            }
+        } else {
+            RequestContext ctx = intrface.getAnnotation(RequestContext.class);
+            validateContextConstraint(ctx, buffer);
+        }
+    }
+
+    private static void validateContextConstraint(RequestContext constraint, 
StringBuilder errors) {
+        String value = ThreadContext.get(constraint.key());
+        if (value != null) {
+            validateConstraints(true, constraint.constraints(), 
constraint.key(), value, errors);
+        } else if (constraint.required()) {
+            appendNewline(errors);
+            errors.append("ThreadContext does not contain required key 
").append(constraint.key());
+        }
+    }
+
+    private static boolean isBlank(String value) {
+        return value != null && value.length() > 0;
+    }
+
+    private static class Property {
+        private final String name;
+        private final boolean isRequired;
+        private final Constraint[] constraints;
+
+        public Property(String name, boolean isRequired, List<Constraint> 
constraints) {
+            this.name = name;
+            this.constraints = constraints.toArray(new 
Constraint[constraints.size()]);
+            this.isRequired = isRequired;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/Constraint.java
----------------------------------------------------------------------
diff --git 
a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/Constraint.java
 
b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/Constraint.java
new file mode 100644
index 0000000..d2f66ba
--- /dev/null
+++ 
b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/Constraint.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.logging.log4j.audit.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Repeatable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Repeatable(Constraints.class)
+public @interface Constraint {
+
+       String constraintType();
+
+       String constraintValue();
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/Constraints.java
----------------------------------------------------------------------
diff --git 
a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/Constraints.java
 
b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/Constraints.java
new file mode 100644
index 0000000..4190fe0
--- /dev/null
+++ 
b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/Constraints.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.logging.log4j.audit.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Container for Constraints.
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Constraints {
+    Constraint[] value();
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/MaxLength.java
----------------------------------------------------------------------
diff --git 
a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/MaxLength.java
 
b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/MaxLength.java
new file mode 100644
index 0000000..fdf1b53
--- /dev/null
+++ 
b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/MaxLength.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.logging.log4j.audit.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Recoreds the maximum length of dynamic attribute names.
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface MaxLength {
+    int value();
+}

Reply via email to