Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP]: Refactoring and minor bugfixes #167

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/audit-test/grails-app/domain/test/Coach.groovy
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package test

import grails.plugins.orm.auditable.Stampable
import grails.plugins.orm.auditable.StampActor

class Coach implements Stampable {
class Coach implements StampActor {

static constraints = {
}
Expand Down
5 changes: 3 additions & 2 deletions examples/audit-test/grails-app/domain/test/Train.groovy
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package test

import grails.plugins.orm.auditable.Stampable
import grails.plugins.orm.auditable.StampActor
import grails.plugins.orm.auditable.StampAutoTimestamp

class Train implements Stampable {
class Train implements StampActor, StampAutoTimestamp{
String number

static constraints = {
Expand Down
2 changes: 1 addition & 1 deletion plugin/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ dependencies {
provided "org.grails.plugins:spring-security-core:3.2.0"

testCompile "org.grails:grails-gorm-testing-support"
testCompile "org.grails:grails-plugin-testing"
testCompile "org.grails:grails-web-testing-support"
}

bootRepackage.enabled = false
Expand Down
33 changes: 0 additions & 33 deletions plugin/grails-app/conf/DefaultAuditLogConfig.groovy

This file was deleted.

19 changes: 19 additions & 0 deletions plugin/grails-app/conf/plugin.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
grails:
plugin:
auditLog:
auditDomainClassName: null
disabled: false
verbose: true
failOnError: false
logIds: true
logFullClassName: true
excluded:
- version
- lastUpdated
- lastUpdatedBy
included: null
mask:
- password
propertyMask: "**********"
defaultActor: 'SYS'
stampEnabled: true
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@
*/
package grails.plugins.orm.auditable

import grails.core.GrailsApplication
import grails.util.Environment
import grails.util.Holders
import groovy.util.logging.Slf4j

/**
Expand All @@ -25,118 +24,12 @@ import groovy.util.logging.Slf4j
*/
@Slf4j
class AuditLoggingConfigUtils {
private static ConfigObject _auditConfig
private static GrailsApplication application

// Constructor. Static methods only
private AuditLoggingConfigUtils() {}

/**
* Parse and load the auditLog configuration.
* @return the configuration
*/
static synchronized ConfigObject getAuditConfig() {
if (_auditConfig == null) {
log.trace 'Building auditLog config since there is no cached config'
reloadAuditConfig()
}
_auditConfig
}

/**
* For testing only.
* @param config the config
*/
static void setAuditConfig(ConfigObject config) {
_auditConfig = config
}

/** Reset the config for testing or after a dev mode Config.groovy change. */
static synchronized void resetAuditConfig() {
_auditConfig = null
log.trace 'reset auditLog config'
}

/**
* Allow a secondary plugin to add config attributes.
* @param className the name of the config class.
*/
static synchronized void loadSecondaryConfig(String className) {
mergeConfig auditConfig, className
log.trace 'loaded secondary config {}', className
}
static @Lazy
ConfigObject auditConfig = { Holders.config.grails.plugin.auditLog }()

/** Force a reload of the auditLog configuration. */
static void reloadAuditConfig() {
mergeConfig ReflectionUtils.auditConfig, 'DefaultAuditLogConfig'
auditConfig = null
log.trace 'reloaded auditLog config'
}

/**
* Merge in a secondary config (provided by plugin as defaults) into the main config.
* @param currentConfig the current configuration
* @param className the name of the config class to load
*/
private static void mergeConfig(ConfigObject currentConfig, String className) {
log.trace("Merging currentConfig with $className")
GroovyClassLoader classLoader = new GroovyClassLoader(Thread.currentThread().contextClassLoader)
ConfigObject secondary = new ConfigSlurper(Environment.current.name).parse(classLoader.loadClass(className))
secondary = secondary.defaultAuditLog as ConfigObject

Collection<String> keysToDefaultEmpty = []
findKeysToDefaultEmpty secondary, '', keysToDefaultEmpty

ConfigObject merged = mergeConfig(currentConfig, secondary)

// having discovered the keys that have map values (since they initially point to empty maps),
// check them again and remove the damage done when Map values are 'flattened'
for (String key in keysToDefaultEmpty) {
Map value = (Map) ReflectionUtils.getConfigProperty(key, merged)
for (Iterator<Map.Entry> iter = value.entrySet().iterator(); iter.hasNext();) {
def entry = iter.next()
if (entry.value instanceof Map) {
iter.remove()
}
}
}

_auditConfig = ReflectionUtils.auditConfig = merged
}

/**
* Merge two configs together. The order is important if <code>secondary</code> is not null then
* start with that and merge the main config on top of that. This lets the <code>secondary</code>
* config act as default values but let user-supplied values in the main config override them.
*
* @param currentConfig the main config, starting from Config.groovy
* @param secondary new default values
* @return the merged configs
*/
private static ConfigObject mergeConfig(ConfigObject currentConfig, ConfigObject secondary) {
log.trace("Merging secondary config on top of currentConfig")
(secondary ?: new ConfigObject()).merge(currentConfig ?: new ConfigObject()) as ConfigObject
}

/**
* Given an unmodified config map with defaults, loop through the keys looking for values that are initially
* empty maps. This will be used after merging to remove map values that cause problems by being included both as
* the result from the ConfigSlurper (which is correct) and as a "flattened" maps which confuse Audit Logging.
* @param m the config map
* @param fullPath the path to this config map, e.g. 'grails.plugin.auditLog
* @param keysToDefaultEmpty a collection of key names to add to
*/
private static void findKeysToDefaultEmpty(Map m, String fullPath, Collection keysToDefaultEmpty) {
m.each { k, v ->
if (v instanceof Map) {
if (v) {
// recurse
findKeysToDefaultEmpty((Map) v, fullPath + '.' + k, keysToDefaultEmpty)
}
else {
// since it's an empty map, capture its path for the cleanup pass
keysToDefaultEmpty << (fullPath + '.' + k).substring(1)
}
}
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package grails.plugins.orm.auditable

trait StampActor {
String createdBy = "N/A"
String lastUpdatedBy = "N/A"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package grails.plugins.orm.auditable

trait StampAutoTimestamp {
Date dateCreated
Date lastUpdated
}
Loading