[SYNCOPE-956] Class cache
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/cea47da1 Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/cea47da1 Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/cea47da1 Branch: refs/heads/master Commit: cea47da1a1510446b7bd62fbc8e45cc8757d6611 Parents: b47d432 Author: Francesco Chicchiriccò <[email protected]> Authored: Tue Oct 10 07:38:09 2017 +0200 Committer: Francesco Chicchiriccò <[email protected]> Committed: Tue Oct 10 08:34:14 2017 +0200 ---------------------------------------------------------------------- .../jpa/dao/JPAImplementationDAO.java | 8 +++- .../core/spring/ImplementationManager.java | 45 ++++++++++++++++---- 2 files changed, 43 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/syncope/blob/cea47da1/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAImplementationDAO.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAImplementationDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAImplementationDAO.java index 091c4b0..9148fbb 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAImplementationDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAImplementationDAO.java @@ -24,6 +24,7 @@ import org.apache.syncope.common.lib.types.ImplementationType; import org.apache.syncope.core.persistence.api.dao.ImplementationDAO; import org.apache.syncope.core.persistence.api.entity.Implementation; import org.apache.syncope.core.persistence.jpa.entity.JPAImplementation; +import org.apache.syncope.core.spring.ImplementationManager; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; @@ -54,7 +55,11 @@ public class JPAImplementationDAO extends AbstractDAO<Implementation> implements @Override public Implementation save(final Implementation implementation) { - return entityManager().merge(implementation); + Implementation merged = entityManager().merge(implementation); + + ImplementationManager.purge(merged.getKey()); + + return merged; } @Override @@ -65,6 +70,7 @@ public class JPAImplementationDAO extends AbstractDAO<Implementation> implements } entityManager().remove(implementation); + ImplementationManager.purge(key); } } http://git-wip-us.apache.org/repos/asf/syncope/blob/cea47da1/core/spring/src/main/java/org/apache/syncope/core/spring/ImplementationManager.java ---------------------------------------------------------------------- diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/ImplementationManager.java b/core/spring/src/main/java/org/apache/syncope/core/spring/ImplementationManager.java index af1b2f7..51c9bf6 100644 --- a/core/spring/src/main/java/org/apache/syncope/core/spring/ImplementationManager.java +++ b/core/spring/src/main/java/org/apache/syncope/core/spring/ImplementationManager.java @@ -19,6 +19,9 @@ package org.apache.syncope.core.spring; import groovy.lang.GroovyClassLoader; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import java.util.Optional; import org.apache.syncope.common.lib.policy.AccountRuleConf; import org.apache.syncope.common.lib.policy.PasswordRuleConf; @@ -39,12 +42,14 @@ public final class ImplementationManager { private static final GroovyClassLoader GROOVY_CLASSLOADER = new GroovyClassLoader(); + private static final Map<String, Class<?>> CLASS_CACHE = Collections.synchronizedMap(new HashMap<>()); + public static Optional<Reportlet> buildReportlet(final Implementation impl) throws InstantiationException, IllegalAccessException { switch (impl.getEngine()) { case GROOVY: - return Optional.of(ImplementationManager.<Reportlet>buildGroovy(impl.getBody())); + return Optional.of(ImplementationManager.<Reportlet>buildGroovy(impl)); case JAVA: default: @@ -78,7 +83,7 @@ public final class ImplementationManager { switch (impl.getEngine()) { case GROOVY: - return Optional.of(ImplementationManager.<AccountRule>buildGroovy(impl.getBody())); + return Optional.of(ImplementationManager.<AccountRule>buildGroovy(impl)); case JAVA: default: @@ -112,7 +117,7 @@ public final class ImplementationManager { switch (impl.getEngine()) { case GROOVY: - return Optional.of(ImplementationManager.<PasswordRule>buildGroovy(impl.getBody())); + return Optional.of(ImplementationManager.<PasswordRule>buildGroovy(impl)); case JAVA: default: @@ -146,28 +151,50 @@ public final class ImplementationManager { switch (impl.getEngine()) { case GROOVY: - return ImplementationManager.<T>buildGroovy(impl.getBody()); + return ImplementationManager.<T>buildGroovy(impl); case JAVA: default: - return ImplementationManager.<T>buildJava(impl.getBody()); + return ImplementationManager.<T>buildJava(impl); } } @SuppressWarnings("unchecked") - private static <T> T buildGroovy(final String classBody) throws InstantiationException, IllegalAccessException { - Class<?> clazz = GROOVY_CLASSLOADER.parseClass(classBody); + private static <T> T buildGroovy(final Implementation impl) + throws InstantiationException, IllegalAccessException { + + Class<?> clazz; + if (CLASS_CACHE.containsKey(impl.getKey())) { + clazz = CLASS_CACHE.get(impl.getKey()); + } else { + clazz = GROOVY_CLASSLOADER.parseClass(impl.getBody()); + CLASS_CACHE.put(impl.getKey(), clazz); + } + return (T) ApplicationContextProvider.getBeanFactory(). createBean(clazz, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false); } @SuppressWarnings("unchecked") - private static <T> T buildJava(final String className) throws ClassNotFoundException { - Class<?> clazz = Class.forName(className); + private static <T> T buildJava(final Implementation impl) + throws ClassNotFoundException { + + Class<?> clazz; + if (CLASS_CACHE.containsKey(impl.getKey())) { + clazz = CLASS_CACHE.get(impl.getKey()); + } else { + clazz = Class.forName(impl.getBody()); + CLASS_CACHE.put(impl.getKey(), clazz); + } + return (T) ApplicationContextProvider.getBeanFactory(). createBean(clazz, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false); } + public static Class<?> purge(final String implementation) { + return CLASS_CACHE.remove(implementation); + } + private ImplementationManager() { // private constructor for static utility class }
