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;
15 import java.util.concurrent.locks.Lock;
17 import javassist.ClassPool;
19 import org.eclipse.xtext.xbase.lib.Extension;
20 import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
21 import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils;
22 import org.opendaylight.yangtools.yang.binding.BindingCodec;
23 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
24 import org.opendaylight.yangtools.yang.binding.util.ClassLoaderUtils;
25 import org.opendaylight.yangtools.yang.common.QName;
26 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
27 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
30 * Abstract base class which defines the baseline for the real {@link TransformerGenerator}.
31 * This class exists to expose the basic interface and common interactions with the rest
34 abstract class AbstractTransformerGenerator {
35 private static final Map<SchemaPath, InstanceIdentifier<?>> PATH_TO_BINDING_IDENTIFIER = new ConcurrentHashMap<>();
38 * The generator has to always use this strategy, otherwise we may end up
39 * will VerificationErrors.
42 protected static final ClassLoadingStrategy CLASS_LOADING_STRATEGY = GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy();
44 protected final TypeResolver typeResolver;
46 protected final JavassistUtils javAssist;
49 * This is effectively final, but we have an implementation circle, where this
50 * class notifies LazyGeneratedCodecRegistry and it calls our methods. The
51 * listener is initialized to non-null before it is exposed.
53 private GeneratorListener listener;
55 protected AbstractTransformerGenerator(final TypeResolver typeResolver, final ClassPool pool) {
56 this.typeResolver = Preconditions.checkNotNull(typeResolver);
57 this.javAssist = JavassistUtils.forClassPool(pool);
60 protected final GeneratorListener getListener() {
61 if (listener == null) {
63 Preconditions.checkState(listener != null, "Implementation not fully initialized");
70 synchronized final void setListener(final GeneratorListener listener) {
71 Preconditions.checkState(this.listener == null, "Implementation already initialized");
72 this.listener = Preconditions.checkNotNull(listener);
75 protected final <V> V runOnClassLoader(final ClassLoader cls, final Callable<V> function) throws Exception {
76 synchronized (javAssist) {
77 javAssist.appendClassLoaderIfMissing(cls);
78 return ClassLoaderUtils.withClassLoader(cls, function);
82 protected final InstanceIdentifier<?> getBindingIdentifierByPath(final SchemaPath path) {
83 return PATH_TO_BINDING_IDENTIFIER.get(path);
86 protected final void putPathToBindingIdentifier(final SchemaPath path, final InstanceIdentifier<?> bindingIdentifier) {
87 PATH_TO_BINDING_IDENTIFIER.put(path, bindingIdentifier);
90 protected final InstanceIdentifier<?> putPathToBindingIdentifier(final SchemaPath path,
91 final InstanceIdentifier<?> bindingIdentifier, final Class<?> childClass) {
92 @SuppressWarnings({ "unchecked", "rawtypes" })
93 InstanceIdentifier<?> newId = bindingIdentifier.builder().child((Class) childClass).build();
94 PATH_TO_BINDING_IDENTIFIER.put(path, newId);
98 protected abstract Class<? extends BindingCodec<Map<QName, Object>, Object>> augmentationTransformerForImpl(Class<?> inputType);
99 protected abstract Class<? extends BindingCodec<Object, Object>> caseCodecForImpl(Class<?> inputType, ChoiceCaseNode node);
100 protected abstract Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifiableImpl(Class<?> parentType);
101 protected abstract Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifierImpl(Class<?> inputType);
102 protected abstract Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerForImpl(Class<?> inputType);
104 // Called from LazyGeneratedCodecRegistry
105 final Class<? extends BindingCodec<Map<QName, Object>, Object>> augmentationTransformerFor(final Class<?> inputType) throws TransformerGeneratorException {
107 return augmentationTransformerForImpl(inputType);
108 } catch (Exception e) {
109 throw TransformerGeneratorException.wrap(inputType, e);
113 final Class<? extends BindingCodec<Object, Object>> caseCodecFor(final Class<?> inputType, final ChoiceCaseNode node) throws TransformerGeneratorException {
115 return caseCodecForImpl(inputType, node);
116 } catch (Exception e) {
117 throw TransformerGeneratorException.wrap(inputType, e);
121 final Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifiable(final Class<?> parentType) throws TransformerGeneratorException {
123 return keyTransformerForIdentifiableImpl(parentType);
124 } catch (Exception e) {
125 throw TransformerGeneratorException.wrap(parentType, e);
129 final Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifier(final Class<?> inputType) throws TransformerGeneratorException {
131 return keyTransformerForIdentifierImpl(inputType);
132 } catch (Exception e) {
133 throw TransformerGeneratorException.wrap(inputType, e);
137 final Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(final Class<?> inputType) throws TransformerGeneratorException {
139 return transformerForImpl(inputType);
140 } catch (Exception e) {
141 throw TransformerGeneratorException.wrap(inputType, e);