You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@johnzon.apache.org by rm...@apache.org on 2016/01/30 19:55:22 UTC
incubator-johnzon git commit: better CDI tracking of jsonb instances,
can still need improvement for often created ones
Repository: incubator-johnzon
Updated Branches:
refs/heads/master 093f095d2 -> 7c29e7868
better CDI tracking of jsonb instances, can still need improvement for often created ones
Project: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/commit/7c29e786
Tree: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/tree/7c29e786
Diff: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/diff/7c29e786
Branch: refs/heads/master
Commit: 7c29e78684843f808c785d94458a7a0356c7856e
Parents: 093f095
Author: Romain Manni-Bucau <rm...@gmail.org>
Authored: Sat Jan 30 19:55:05 2016 +0100
Committer: Romain Manni-Bucau <rm...@gmail.org>
Committed: Sat Jan 30 19:55:05 2016 +0100
----------------------------------------------------------------------
.../apache/johnzon/jsonb/JohnzonBuilder.java | 90 ++++++++++++++------
.../java/org/apache/johnzon/jsonb/cdi/CDIs.java | 54 ++++++++++++
.../johnzon/jsonb/cdi/JohnzonCdiExtension.java | 75 ++++++++++++++++
.../javax.enterprise.inject.spi.Extension | 1 +
4 files changed, 196 insertions(+), 24 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/7c29e786/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
----------------------------------------------------------------------
diff --git a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
index 587e5e8..c0d9c1f 100644
--- a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
+++ b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
@@ -20,11 +20,13 @@ package org.apache.johnzon.jsonb;
import org.apache.johnzon.core.AbstractJsonFactory;
import org.apache.johnzon.core.JsonGeneratorFactoryImpl;
+import org.apache.johnzon.jsonb.cdi.CDIs;
import org.apache.johnzon.jsonb.converter.JohnzonJsonbAdapter;
import org.apache.johnzon.jsonb.factory.SimpleJohnzonAdapterFactory;
import org.apache.johnzon.jsonb.spi.JohnzonAdapterFactory;
import org.apache.johnzon.mapper.Adapter;
import org.apache.johnzon.mapper.Converter;
+import org.apache.johnzon.mapper.Mapper;
import org.apache.johnzon.mapper.MapperBuilder;
import org.apache.johnzon.mapper.internal.AdapterKey;
import org.apache.johnzon.mapper.internal.ConverterAdapter;
@@ -75,9 +77,13 @@ import static javax.json.bind.config.PropertyNamingStrategy.IDENTITY;
import static javax.json.bind.config.PropertyOrderStrategy.LEXICOGRAPHICAL;
public class JohnzonBuilder implements JsonbBuilder {
+ private static final Object NO_BM = new Object();
+
private final MapperBuilder builder = new MapperBuilder();
private JsonProvider jsonp;
private JsonbConfig config;
+ private Object beanManager;
+ private CDIs cdiIntegration;
@Override
public JsonbBuilder withConfig(final JsonbConfig config) {
@@ -155,30 +161,31 @@ public class JohnzonBuilder implements JsonbBuilder {
final Map<AdapterKey, Adapter<?, ?>> defaultConverters = createJava8Converters(builder);
+ final JohnzonAdapterFactory factory = config.getProperty("johnzon.factory").map(val -> {
+ if (JohnzonAdapterFactory.class.isInstance(val)) {
+ return JohnzonAdapterFactory.class.cast(val);
+ }
+ if (String.class.isInstance(val)) {
+ try {
+ return JohnzonAdapterFactory.class.cast(tccl().loadClass(val.toString()).newInstance());
+ } catch (final InstantiationException | ClassNotFoundException | IllegalAccessException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+ if (Class.class.isInstance(val)) {
+ try {
+ return JohnzonAdapterFactory.class.cast(Class.class.cast(val).newInstance());
+ } catch (final InstantiationException | IllegalAccessException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+ throw new IllegalArgumentException("Unsupported factory: " + val);
+ }).orElseGet(this::findFactory);
final JsonbAccessMode accessMode = new JsonbAccessMode(
propertyNamingStrategy, orderValue, visibilityStrategy,
!namingStrategyValue.orElse("").equals(PropertyNamingStrategy.CASE_INSENSITIVE),
defaultConverters,
- config.getProperty("johnzon.factory").map(val -> {
- if (JohnzonAdapterFactory.class.isInstance(val)) {
- return JohnzonAdapterFactory.class.cast(val);
- }
- if (String.class.isInstance(val)) {
- try {
- return JohnzonAdapterFactory.class.cast(tccl().loadClass(val.toString()).newInstance());
- } catch (final InstantiationException | ClassNotFoundException | IllegalAccessException e) {
- throw new IllegalArgumentException(e);
- }
- }
- if (Class.class.isInstance(val)) {
- try {
- return JohnzonAdapterFactory.class.cast(Class.class.cast(val).newInstance());
- } catch (final InstantiationException | IllegalAccessException e) {
- throw new IllegalArgumentException(e);
- }
- }
- throw new IllegalArgumentException("Unsupported factory: " + val);
- }).orElseGet(this::findFactory));
+ factory);
builder.setAccessMode(accessMode);
@@ -224,14 +231,49 @@ public class JohnzonBuilder implements JsonbBuilder {
}
});
- return new JohnsonJsonb(builder.addCloseable(accessMode).build());
+ getBeanManager(); // force detection
+
+ final boolean useCdi = cdiIntegration != null && cdiIntegration.isCanWrite();
+ final Mapper mapper = builder.addCloseable(accessMode).build();
+
+ return useCdi ? new JohnsonJsonb(mapper) {
+ {
+ cdiIntegration.track(this);
+ }
+
+ @Override
+ public void close() {
+ try {
+ super.close();
+ } finally {
+ if (cdiIntegration.isCanWrite()) {
+ cdiIntegration.untrack(this);
+ }
+ }
+ }
+ } : new JohnsonJsonb(mapper);
+ }
+
+ private Object getBeanManager() {
+ if (beanManager == null) {
+ try { // don't trigger CDI is not there
+ final Class<?> cdi = tccl().loadClass("javax.enterprise.inject.spi.CDI");
+ final Object cdiInstance = cdi.getMethod("current").invoke(null);
+ beanManager = cdi.getMethod("getBeanManager").invoke(cdiInstance);
+ cdiIntegration = new CDIs(beanManager);
+ } catch (final NoClassDefFoundError | Exception e) {
+ beanManager = NO_BM;
+ }
+ }
+ return beanManager;
}
private JohnzonAdapterFactory findFactory() {
+ if (getBeanManager() == NO_BM || config.getProperty("johnzon.skip-cdi")
+ .map(s -> "true".equalsIgnoreCase(String.valueOf(s))).orElse(false)) {
+ return new SimpleJohnzonAdapterFactory();
+ }
try { // don't trigger CDI is not there
- final Class<?> cdi = tccl().loadClass("javax.enterprise.inject.spi.CDI");
- final Object cdiInstance = cdi.getMethod("current").invoke(null);
- final Object beanManager = cdi.getMethod("getBeanManager").invoke(cdiInstance);
return new org.apache.johnzon.jsonb.factory.CdiJohnzonAdapterFactory(beanManager);
} catch (final NoClassDefFoundError | Exception e) {
return new SimpleJohnzonAdapterFactory();
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/7c29e786/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/cdi/CDIs.java
----------------------------------------------------------------------
diff --git a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/cdi/CDIs.java b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/cdi/CDIs.java
new file mode 100644
index 0000000..50e2d5f
--- /dev/null
+++ b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/cdi/CDIs.java
@@ -0,0 +1,54 @@
+/*
+ * 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.johnzon.jsonb.cdi;
+
+import org.apache.johnzon.jsonb.JohnsonJsonb;
+
+// helper class to lazy trigger CDI deps
+public final class CDIs {
+ private final JohnzonCdiExtension tracker;
+
+ public CDIs(final Object beanManager) {
+ this.tracker = Lazy.load(beanManager);
+ }
+
+ public void track(final JohnsonJsonb johnsonJsonb) {
+ tracker.track(johnsonJsonb);
+ }
+
+ public void untrack(final JohnsonJsonb johnsonJsonb) {
+ tracker.untrack(johnsonJsonb);
+ }
+
+ public boolean isCanWrite() {
+ return tracker.isCanWrite();
+ }
+
+ private static class Lazy {
+ private Lazy() {
+ // no-op
+ }
+
+ private static JohnzonCdiExtension load(final Object beanManager) {
+ final javax.enterprise.inject.spi.BeanManager bm = javax.enterprise.inject.spi.BeanManager.class.cast(beanManager);
+ return JohnzonCdiExtension.class.cast(
+ bm.getReference(bm.resolve(bm.getBeans(JohnzonCdiExtension.class)), JohnzonCdiExtension.class, null));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/7c29e786/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/cdi/JohnzonCdiExtension.java
----------------------------------------------------------------------
diff --git a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/cdi/JohnzonCdiExtension.java b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/cdi/JohnzonCdiExtension.java
new file mode 100644
index 0000000..d925659
--- /dev/null
+++ b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/cdi/JohnzonCdiExtension.java
@@ -0,0 +1,75 @@
+/*
+ * 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.johnzon.jsonb.cdi;
+
+import org.apache.johnzon.jsonb.JohnsonJsonb;
+
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.BeforeBeanDiscovery;
+import javax.enterprise.inject.spi.BeforeShutdown;
+import javax.enterprise.inject.spi.Extension;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.concurrent.locks.ReentrantLock;
+
+public class JohnzonCdiExtension implements Extension {
+ private final Collection<JohnsonJsonb> jsonbs = new ArrayList<>();
+ private final ReentrantLock lock = new ReentrantLock();
+ private volatile boolean canWrite = false;
+
+ public boolean isCanWrite() {
+ return canWrite;
+ }
+
+ public void track(final JohnsonJsonb jsonb) {
+ if (!canWrite) {
+ throw new IllegalStateException("CDI context already shutdown");
+ }
+ lock.lock();
+ try {
+ jsonbs.add(jsonb);
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public void untrack(final JohnsonJsonb jsonb) {
+ synchronized (this) {
+ lock.lock();
+ try {
+ if (!jsonbs.remove(jsonb)) {
+ return;
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+ jsonb.close();
+ }
+
+ void started(@Observes final BeforeBeanDiscovery beforeBeanDiscovery) {
+ canWrite = true;
+ }
+
+ void cleanUp(@Observes final BeforeShutdown beforeShutdown) {
+ canWrite = false;
+ jsonbs.forEach(this::untrack);
+ jsonbs.clear();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/7c29e786/johnzon-jsonb/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
----------------------------------------------------------------------
diff --git a/johnzon-jsonb/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/johnzon-jsonb/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
new file mode 100644
index 0000000..89497eb
--- /dev/null
+++ b/johnzon-jsonb/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
@@ -0,0 +1 @@
+org.apache.johnzon.jsonb.cdi.JohnzonCdiExtension