2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.sal.binding.generator.impl;
10 import com.google.common.base.Preconditions;
13 import java.util.concurrent.Callable;
14 import java.util.concurrent.ConcurrentHashMap;
16 import javassist.ClassPool;
18 import org.eclipse.xtext.xbase.lib.Extension;
19 import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
20 import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils;
21 import org.opendaylight.yangtools.yang.binding.BindingCodec;
22 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
23 import org.opendaylight.yangtools.yang.binding.util.ClassLoaderUtils;
24 import org.opendaylight.yangtools.yang.common.QName;
25 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
26 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
29 * Abstract base class which defines the baseline for the real {@link TransformerGenerator}.
30 * This class exists to expose the basic interface and common interactions with the rest
33 abstract class AbstractTransformerGenerator {
34 private static final Map<SchemaPath, InstanceIdentifier<?>> PATH_TO_BINDING_IDENTIFIER = new ConcurrentHashMap<>();
37 * The generator has to always use this strategy, otherwise we may end up
38 * will VerificationErrors.
41 protected static final ClassLoadingStrategy CLASS_LOADING_STRATEGY = GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy();
43 protected final TypeResolver typeResolver;
45 protected final JavassistUtils javAssist;
48 * This is effectively final, but we have an implementation circle, where this
49 * class notifies LazyGeneratedCodecRegistry and it calls our methods. The
50 * listener is initialized to non-null before it is exposed.
52 private GeneratorListener listener;
54 protected AbstractTransformerGenerator(final TypeResolver typeResolver, final ClassPool pool) {
55 this.typeResolver = Preconditions.checkNotNull(typeResolver);
56 this.javAssist = JavassistUtils.forClassPool(pool);
59 protected final GeneratorListener getListener() {
60 if (listener == null) {
62 Preconditions.checkState(listener != null, "Implementation not fully initialized");
69 synchronized final void setListener(final GeneratorListener listener) {
70 Preconditions.checkState(this.listener == null, "Implementation already initialized");
71 this.listener = Preconditions.checkNotNull(listener);
74 protected final <V> V runOnClassLoader(final ClassLoader cls, final Callable<V> function) throws Exception {
75 synchronized (javAssist) {
76 javAssist.appendClassLoaderIfMissing(cls);
77 return ClassLoaderUtils.withClassLoader(cls, function);
81 protected final InstanceIdentifier<?> getBindingIdentifierByPath(final SchemaPath path) {
82 return PATH_TO_BINDING_IDENTIFIER.get(path);
85 protected final void putPathToBindingIdentifier(final SchemaPath path, final InstanceIdentifier<?> bindingIdentifier) {
86 PATH_TO_BINDING_IDENTIFIER.put(path, bindingIdentifier);
89 protected final InstanceIdentifier<?> putPathToBindingIdentifier(final SchemaPath path,
90 final InstanceIdentifier<?> bindingIdentifier, final Class<?> childClass) {
91 @SuppressWarnings({ "unchecked", "rawtypes" })
92 InstanceIdentifier<?> newId = bindingIdentifier.builder().child((Class) childClass).build();
93 PATH_TO_BINDING_IDENTIFIER.put(path, newId);
97 protected abstract Class<? extends BindingCodec<Map<QName, Object>, Object>> augmentationTransformerForImpl(Class<?> inputType);
98 protected abstract Class<? extends BindingCodec<Object, Object>> caseCodecForImpl(Class<?> inputType, ChoiceCaseNode node);
99 protected abstract Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifiableImpl(Class<?> parentType);
100 protected abstract Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifierImpl(Class<?> inputType);
101 protected abstract Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerForImpl(Class<?> inputType);
103 // Called from LazyGeneratedCodecRegistry
104 final Class<? extends BindingCodec<Map<QName, Object>, Object>> augmentationTransformerFor(final Class<?> inputType) throws TransformerGeneratorException {
106 return augmentationTransformerForImpl(inputType);
107 } catch (Exception e) {
108 throw TransformerGeneratorException.wrap(inputType, e);
112 final Class<? extends BindingCodec<Object, Object>> caseCodecFor(final Class<?> inputType, final ChoiceCaseNode node) throws TransformerGeneratorException {
114 return caseCodecForImpl(inputType, node);
115 } catch (Exception e) {
116 throw TransformerGeneratorException.wrap(inputType, e);
120 final Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifiable(final Class<?> parentType) throws TransformerGeneratorException {
122 return keyTransformerForIdentifiableImpl(parentType);
123 } catch (Exception e) {
124 throw TransformerGeneratorException.wrap(parentType, e);
128 final Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifier(final Class<?> inputType) throws TransformerGeneratorException {
130 return keyTransformerForIdentifierImpl(inputType);
131 } catch (Exception e) {
132 throw TransformerGeneratorException.wrap(inputType, e);
136 final Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(final Class<?> inputType) throws TransformerGeneratorException {
138 return transformerForImpl(inputType);
139 } catch (Exception e) {
140 throw TransformerGeneratorException.wrap(inputType, e);