/* * Copyright (c) 2015 Red Hat, Inc. and/or its affiliates. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Cheng Fang - Initial API and implementation */ package org.jberet.creation; import java.lang.annotation.Annotation; import java.util.Map; import java.util.concurrent.ConcurrentMap; import javax.enterprise.context.spi.Context; import javax.enterprise.context.spi.Contextual; import javax.enterprise.context.spi.CreationalContext; import org.jberet.cdi.JobScoped; import org.jberet.runtime.context.JobContextImpl; public class JobScopedContextImpl implements Context { static final JobScopedContextImpl INSTANCE = new JobScopedContextImpl(); private JobScopedContextImpl() { } @Override public Class<? extends Annotation> getScope() { return JobScoped.class; } @Override @SuppressWarnings("unchecked") public <T> T get(final Contextual<T> contextual, final CreationalContext<T> creationalContext) { final ConcurrentMap<Contextual<?>, ScopedInstance<?>> jobScopedBeans = getJobScopedBeans(); ScopedInstance<?> existing = jobScopedBeans.get(contextual); if (existing == null) { final T instance = contextual.create(creationalContext); existing = jobScopedBeans.putIfAbsent(contextual, new ScopedInstance<T>(instance, creationalContext)); if (existing == null) { return instance; } else { return (T) existing.instance; } } else { return (T) existing.instance; } } @Override @SuppressWarnings("unchecked") public <T> T get(final Contextual<T> contextual) { final ScopedInstance<?> existing = getJobScopedBeans().get(contextual); return existing == null ? null : (T) existing.instance; } @Override public boolean isActive() { return ArtifactCreationContext.getCurrentArtifactCreationContext().jobContext != null; } private ConcurrentMap<Contextual<?>, ScopedInstance<?>> getJobScopedBeans() { final JobContextImpl jobContext = ArtifactCreationContext.getCurrentArtifactCreationContext().jobContext; return jobContext.getScopedBeans(); } public static final class ScopedInstance<T> { final T instance; final CreationalContext<T> creationalContext; public ScopedInstance(final T instance, final CreationalContext<T> creationalContext) { this.instance = instance; this.creationalContext = creationalContext; } @SuppressWarnings("unchecked") public static void destroy(final ConcurrentMap<Contextual<?>, JobScopedContextImpl.ScopedInstance<?>> scopedBeans) { if (scopedBeans.size() > 0) { for (final Map.Entry<Contextual<?>, JobScopedContextImpl.ScopedInstance<?>> e : scopedBeans.entrySet()) { final Contextual<?> contextual = e.getKey(); final ScopedInstance<?> value = e.getValue(); ((Contextual) contextual).destroy(value.instance, value.creationalContext); } scopedBeans.clear(); } } } }