This removes deprecated use of javassist.
Change-Id: Ia5686ce24052222cadb7465e66916b0db5b05ff3
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
- <dependency>
- <groupId>org.javassist</groupId>
- <artifactId>javassist</artifactId>
- </dependency>
<dependency>
<groupId>org.opendaylight.mdsal</groupId>
<artifactId>mdsal-binding-api</artifactId>
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import java.util.concurrent.ExecutorService;
-import javassist.ClassPool;
@Beta
public class BindingBrokerTestFactory {
-
- private static final ClassPool CLASS_POOL = ClassPool.getDefault();
-
private boolean startWithParsedSchema = true;
private ExecutorService executor;
- private ClassPool classPool;
public boolean isStartWithParsedSchema() {
return startWithParsedSchema;
ListeningExecutorService listenableExecutor = MoreExecutors.listeningDecorator(executor);
return new BindingTestContext(listenableExecutor, startWithParsedSchema);
}
-
- @Deprecated
- public ClassPool getClassPool() {
- if (classPool == null) {
- return CLASS_POOL;
- }
-
- return classPool;
- }
-
- @Deprecated
- public void setClassPool(final ClassPool classPool) {
- this.classPool = classPool;
- }
}
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import java.util.Set;
-import javassist.ClassPool;
import org.opendaylight.mdsal.binding.api.DataBroker;
import org.opendaylight.mdsal.binding.api.MountPointService;
import org.opendaylight.mdsal.binding.api.NotificationPublishService;
return codec;
}
- @Deprecated
- protected BindingTestContext(final ListeningExecutorService executor,
- final ClassPool classPool, final boolean startWithSchema) {
- this(executor, startWithSchema);
- }
-
protected BindingTestContext(final ListeningExecutorService executor, final boolean startWithSchema) {
this.executor = executor;
this.startWithSchema = startWithSchema;
</properties>
<dependencies>
- <dependency>
- <groupId>org.javassist</groupId>
- <artifactId>javassist</artifactId>
- </dependency>
<dependency>
<!-- We are going to shade this -->
<groupId>net.bytebuddy</groupId>
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. 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
- */
-package org.opendaylight.mdsal.binding.dom.codec.gen.impl;
-
-/**
- * Package-private base class for sharing the loading capability.
- *
- * @deprecated This class is superseded by an internal implementation.
- */
-@Deprecated
-abstract class AbstractGenerator {
- /**
- * Ensure that the serializer class for specified class is loaded and return its name.
- *
- * @param cls Data object class
- * @return Serializer class name
- */
- protected abstract String loadSerializerFor(Class<?> cls);
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. 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
- */
-package org.opendaylight.mdsal.binding.dom.codec.gen.impl;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Map.Entry;
-import javassist.CannotCompileException;
-import javassist.CtClass;
-import javassist.CtField;
-import javassist.CtMethod;
-import javassist.Modifier;
-import javassist.NotFoundException;
-import org.opendaylight.mdsal.binding.dom.codec.gen.spi.StaticConstantDefinition;
-import org.opendaylight.mdsal.binding.dom.codec.util.AugmentableDispatchSerializer;
-import org.opendaylight.mdsal.binding.generator.util.BindingRuntimeContext;
-import org.opendaylight.mdsal.binding.generator.util.JavassistUtils;
-import org.opendaylight.mdsal.binding.model.api.GeneratedType;
-import org.opendaylight.mdsal.binding.model.util.Types;
-import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
-import org.opendaylight.yangtools.util.ClassLoaderUtils;
-import org.opendaylight.yangtools.yang.binding.BindingStreamEventWriter;
-import org.opendaylight.yangtools.yang.binding.DataContainer;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.DataObjectSerializerImplementation;
-import org.opendaylight.yangtools.yang.binding.DataObjectSerializerRegistry;
-import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DocumentedNode.WithStatus;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Deprecated
-abstract class AbstractStreamWriterGenerator extends AbstractGenerator implements DataObjectSerializerGenerator {
- private static final Logger LOG = LoggerFactory.getLogger(AbstractStreamWriterGenerator.class);
-
- protected static final String SERIALIZE_METHOD_NAME = "serialize";
- protected static final AugmentableDispatchSerializer AUGMENTABLE = new AugmentableDispatchSerializer();
- private static final Field FIELD_MODIFIERS = getModifiersField();
-
- private final LoadingCache<Class<?>, DataObjectSerializerImplementation> implementations;
- private final CtClass[] serializeArguments;
- private final JavassistUtils javassist;
- private BindingRuntimeContext context;
-
- private static Field getModifiersField() {
- /*
- * Cache reflection access to field modifiers field. We need this to set
- * fix the static declared fields to final once we initialize them. If we
- * cannot get access, that's fine, too.
- */
- final Field field;
- try {
- field = Field.class.getDeclaredField("modifiers");
- } catch (NoSuchFieldException | SecurityException e) {
- LOG.warn("Could not get modifiers field, serializers run at decreased efficiency", e);
- return null;
- }
-
- try {
- AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
- field.setAccessible(true);
- return null;
- });
- } catch (SecurityException e) {
- LOG.warn("Could not get access to modifiers field, serializers run at decreased efficiency", e);
- return null;
- }
-
- return field;
- }
-
- protected AbstractStreamWriterGenerator(final JavassistUtils utils) {
- this.javassist = requireNonNull(utils, "JavassistUtils instance is required.");
- synchronized (javassist) {
- this.serializeArguments = new CtClass[] {
- javassist.asCtClass(DataObjectSerializerRegistry.class),
- javassist.asCtClass(DataObject.class),
- javassist.asCtClass(BindingStreamEventWriter.class),
- };
- javassist.appendClassLoaderIfMissing(DataObjectSerializerPrototype.class.getClassLoader());
- }
- this.implementations = CacheBuilder.newBuilder()
- .removalListener(notification -> LOG.debug("onRemoval: cause={}, wasEvicted={}",
- notification.getCause(), notification.wasEvicted()))
- .weakKeys().build(new SerializerImplementationLoader());
- LOG.debug("AbstractStreamWriterGenerator constructor, new instance: {}", this);
- }
-
- @Override
- public final DataObjectSerializerImplementation getSerializer(final Class<?> type) {
- return implementations.getUnchecked(type);
- }
-
- @Override
- public final void onBindingRuntimeContextUpdated(final BindingRuntimeContext runtime) {
- this.context = runtime;
- LOG.debug("onBindingRuntimeContextUpdated() : {}", runtime);
- }
-
- @Override
- protected final String loadSerializerFor(final Class<?> cls) {
- return getSerializer(cls).getClass().getName();
- }
-
- private final class SerializerImplementationLoader
- extends CacheLoader<Class<?>, DataObjectSerializerImplementation> {
-
- private static final String GETINSTANCE_METHOD_NAME = "getInstance";
- private static final String SERIALIZER_SUFFIX = "$StreamWriter";
-
- private String getSerializerName(final Class<?> type) {
- return type.getName() + SERIALIZER_SUFFIX;
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public DataObjectSerializerImplementation load(final Class<?> type) throws Exception {
- checkArgument(BindingReflections.isBindingClass(type));
- checkArgument(DataContainer.class.isAssignableFrom(type),
- "DataContainer is not assingnable from %s from classloader %s.", type, type.getClassLoader());
-
- final String serializerName = getSerializerName(type);
-
- Class<? extends DataObjectSerializerImplementation> cls;
- try {
- cls = (Class<? extends DataObjectSerializerImplementation>) ClassLoaderUtils
- .loadClass(type.getClassLoader(), serializerName);
- } catch (final ClassNotFoundException e) {
- cls = generateSerializer(type, serializerName);
- }
-
- final DataObjectSerializerImplementation obj =
- (DataObjectSerializerImplementation) cls.getDeclaredMethod(GETINSTANCE_METHOD_NAME).invoke(null);
- LOG.trace("Loaded serializer {} for class {}", obj, type);
- return obj;
- }
-
- private Class<? extends DataObjectSerializerImplementation> generateSerializer(final Class<?> type,
- final String serializerName) throws CannotCompileException, IllegalAccessException,
- IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException,
- NoSuchFieldException {
- LOG.debug("generateSerializer() due to Cache miss: typeName={}, typeClassLoader={}, serializerName={}",
- type.getTypeName(), type.getClassLoader(), serializerName);
- final DataObjectSerializerSource source = generateEmitterSource(type, serializerName);
- final CtClass poolClass = generateEmitter0(type, source, serializerName);
- final Class<? extends DataObjectSerializerImplementation> cls =
- poolClass.toClass(type.getClassLoader(), type.getProtectionDomain())
- .asSubclass(DataObjectSerializerImplementation.class);
-
- /*
- * Due to OSGi class loader rules we cannot initialize the fields during
- * construction, as the initializer expressions do not see our implementation
- * classes. This should be almost as good as that, as we are resetting the
- * fields to final before ever leaking the class.
- */
- for (final StaticConstantDefinition constant : source.getStaticConstants()) {
- final Field field = cls.getDeclaredField(constant.getName());
- field.setAccessible(true);
- field.set(null, constant.getValue());
-
- if (FIELD_MODIFIERS != null) {
- FIELD_MODIFIERS.setInt(field, field.getModifiers() | Modifier.FINAL);
- }
- }
-
- return cls;
- }
- }
-
- private DataObjectSerializerSource generateEmitterSource(final Class<?> type, final String serializerName) {
- Types.typeForClass(type);
- javassist.appendClassLoaderIfMissing(type.getClassLoader());
- final Entry<GeneratedType, WithStatus> typeWithSchema = context.getTypeWithSchema(type);
- final GeneratedType generatedType = typeWithSchema.getKey();
- final WithStatus schema = typeWithSchema.getValue();
-
- final DataObjectSerializerSource source;
- if (schema instanceof ContainerSchemaNode) {
- source = generateContainerSerializer(generatedType, (ContainerSchemaNode) schema);
- } else if (schema instanceof ListSchemaNode) {
- final ListSchemaNode casted = (ListSchemaNode) schema;
- if (casted.getKeyDefinition().isEmpty()) {
- source = generateUnkeyedListEntrySerializer(generatedType, casted);
- } else {
- source = generateMapEntrySerializer(generatedType, casted);
- }
- } else if (schema instanceof AugmentationSchemaNode) {
- source = generateSerializer(generatedType,(AugmentationSchemaNode) schema);
- } else if (schema instanceof CaseSchemaNode) {
- source = generateCaseSerializer(generatedType,(CaseSchemaNode) schema);
- } else if (schema instanceof NotificationDefinition) {
- source = generateNotificationSerializer(generatedType,(NotificationDefinition) schema);
- } else {
- throw new UnsupportedOperationException("Schema type " + schema.getClass() + " is not supported");
- }
- return source;
- }
-
- private CtClass generateEmitter0(final Class<?> type, final DataObjectSerializerSource source,
- final String serializerName) {
- final CtClass product;
-
- /*
- * getSerializerBody() has side effects, such as loading classes and codecs, it should be run in model class
- * loader in order to correctly reference load child classes.
- *
- * Furthermore the fact that getSerializedBody() can trigger other code generation to happen, we need to take
- * care of this before calling instantiatePrototype(), as that will call our customizer with the lock held,
- * hence any code generation will end up being blocked on the javassist lock.
- */
- final String body = ClassLoaderUtils.getWithClassLoader(type.getClassLoader(), source::getSerializerBody)
- .toString();
-
- try {
- product = javassist.instantiatePrototype(DataObjectSerializerPrototype.class.getName(), serializerName,
- cls -> {
- // Generate any static fields
- for (final StaticConstantDefinition def : source.getStaticConstants()) {
- final CtField field = new CtField(javassist.asCtClass(def.getType()), def.getName(), cls);
- field.setModifiers(Modifier.PRIVATE + Modifier.STATIC);
- cls.addField(field);
- }
-
- // Replace serialize() -- may reference static fields
- final CtMethod serializeTo = cls.getDeclaredMethod(SERIALIZE_METHOD_NAME, serializeArguments);
- serializeTo.setBody(body);
-
- // The prototype is not visible, so we need to take care of that
- cls.setModifiers(Modifier.setPublic(cls.getModifiers()));
- });
- } catch (NotFoundException | CannotCompileException e) {
- LOG.error("Failed to instatiate serializer {}", source, e);
- throw new LinkageError("Unexpected instantation problem: serializer prototype not found", e);
- }
- return product;
- }
-
- /**
- * Generates serializer source code for supplied container node, which will read supplied binding type and invoke
- * proper methods on supplied {@link BindingStreamEventWriter}.
- *
- * <p>
- * Implementation is required to recursively invoke events for all reachable binding objects.
- *
- * @param type Binding type of container
- * @param node Schema of container
- * @return Source for container node writer
- */
- protected abstract DataObjectSerializerSource generateContainerSerializer(GeneratedType type,
- ContainerSchemaNode node);
-
- /**
- * Generates serializer source for supplied case node, which will read supplied binding type and invoke proper
- * methods on supplied {@link BindingStreamEventWriter}.
- *
- * <p>
- * Implementation is required to recursively invoke events for all reachable binding objects.
- *
- * @param type Binding type of case
- * @param node Schema of case
- * @return Source for case node writer
- */
- protected abstract DataObjectSerializerSource generateCaseSerializer(GeneratedType type, CaseSchemaNode node);
-
- /**
- * Generates serializer source for supplied list node, which will read supplied binding type and invoke proper
- * methods on supplied {@link BindingStreamEventWriter}.
- *
- * <p>
- * Implementation is required to recursively invoke events for all reachable binding objects.
- *
- * @param type Binding type of list
- * @param node Schema of list
- * @return Source for list node writer
- */
- protected abstract DataObjectSerializerSource generateMapEntrySerializer(GeneratedType type, ListSchemaNode node);
-
- /**
- * Generates serializer source for supplied list node, which will read supplied binding type and invoke proper
- * methods on supplied {@link BindingStreamEventWriter}.
- *
- * <p>
- * Implementation is required to recursively invoke events for all reachable binding objects.
- *
- * @param type Binding type of list
- * @param node Schema of list
- * @return Source for list node writer
- */
- protected abstract DataObjectSerializerSource generateUnkeyedListEntrySerializer(GeneratedType type,
- ListSchemaNode node);
-
- /**
- * Generates serializer source for supplied augmentation node, which will read supplied binding type and invoke
- * proper methods on supplied {@link BindingStreamEventWriter}.
- *
- * <p>
- * Implementation is required to recursively invoke events for all reachable binding objects.
- *
- * @param type Binding type of augmentation
- * @param schema Schema of augmentation
- * @return Source for augmentation node writer
- */
- protected abstract DataObjectSerializerSource generateSerializer(GeneratedType type, AugmentationSchemaNode schema);
-
- /**
- * Generates serializer source for notification node, which will read supplied binding type and invoke proper
- * methods on supplied {@link BindingStreamEventWriter}.
- *
- * <p>
- * Implementation is required to recursively invoke events for all reachable binding objects.
- *
- * @param type Binding type of notification
- * @param node Schema of notification
- * @return Source for notification node writer
- */
- protected abstract DataObjectSerializerSource generateNotificationSerializer(GeneratedType type,
- NotificationDefinition node);
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. 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
- */
-package org.opendaylight.mdsal.binding.dom.codec.gen.impl;
-
-import org.opendaylight.mdsal.binding.model.api.GeneratedType;
-import org.opendaylight.yangtools.yang.binding.DataObjectSerializerImplementation;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-
-@Deprecated
-abstract class AugmentableDataNodeContainerEmitterSource extends DataNodeContainerSerializerSource {
- private static final String AUGMENTABLE_SERIALIZER = "AUGMENTABLE_SERIALIZER";
-
- AugmentableDataNodeContainerEmitterSource(final AbstractStreamWriterGenerator generator, final GeneratedType type,
- final DataNodeContainer node) {
- super(generator, type, node);
- /*
- * Eventhough intuition says the serializer could reference the generator directly, that is not true in OSGi
- * environment -- so we need to resolve the reference first and inject it as a static constant.
- */
- staticConstant(AUGMENTABLE_SERIALIZER, DataObjectSerializerImplementation.class,
- StreamWriterGenerator.AUGMENTABLE);
- }
-
- @Override
- protected void emitAfterBody(final StringBuilder sb) {
- sb.append(statement(invoke(AUGMENTABLE_SERIALIZER, "serialize", REGISTRY, INPUT, STREAM)));
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. 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
- */
-package org.opendaylight.mdsal.binding.dom.codec.gen.impl;
-
-import static com.google.common.base.Preconditions.checkState;
-import static java.util.Objects.requireNonNull;
-
-import java.util.HashMap;
-import java.util.Map;
-import org.opendaylight.mdsal.binding.dom.codec.util.BindingSchemaMapping;
-import org.opendaylight.mdsal.binding.dom.codec.util.ChoiceDispatchSerializer;
-import org.opendaylight.mdsal.binding.model.api.GeneratedType;
-import org.opendaylight.mdsal.binding.model.api.MethodSignature;
-import org.opendaylight.mdsal.binding.model.api.ParameterizedType;
-import org.opendaylight.mdsal.binding.model.api.Type;
-import org.opendaylight.yangtools.yang.binding.BindingSerializer;
-import org.opendaylight.yangtools.yang.binding.BindingStreamEventWriter;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.DataObjectSerializerImplementation;
-import org.opendaylight.yangtools.yang.binding.DataObjectSerializerRegistry;
-import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Deprecated
-abstract class DataNodeContainerSerializerSource extends DataObjectSerializerSource {
-
- private static final Logger LOG = LoggerFactory.getLogger(DataNodeContainerSerializerSource.class);
-
- protected static final String INPUT = "_input";
- private static final String CHOICE_PREFIX = "CHOICE_";
-
- protected final DataNodeContainer schemaNode;
- private final GeneratedType dtoType;
-
- DataNodeContainerSerializerSource(final AbstractGenerator generator, final GeneratedType type,
- final DataNodeContainer node) {
- super(generator);
- this.dtoType = requireNonNull(type);
- this.schemaNode = requireNonNull(node);
- }
-
- /**
- * Return the character sequence which should be used for start event.
- *
- * @return Start event character sequence
- */
- protected abstract CharSequence emitStartEvent();
-
- @Override
- protected CharSequence getSerializerBody() {
- final StringBuilder sb = new StringBuilder()
- .append("{\n")
- .append(statement(assign(DataObjectSerializerRegistry.class, REGISTRY, "$1")))
- .append(statement(assign(dtoType, INPUT, cast(dtoType, "$2"))))
- .append(statement(assign(BindingStreamEventWriter.class, STREAM,
- cast(BindingStreamEventWriter.class, "$3"))))
- .append(statement(assign(BindingSerializer.class, SERIALIZER, null)))
- .append("if (")
- .append(STREAM)
- .append(" instanceof ")
- .append(BindingSerializer.class.getName())
- .append(") {")
- .append(statement(assign(SERIALIZER, cast(BindingSerializer.class, STREAM))))
- .append('}')
- .append(statement(emitStartEvent()));
-
- emitBody(sb);
- emitAfterBody(sb);
-
- return sb.append(statement(endNode()))
- .append(statement("return null"))
- .append('}');
- }
-
- /**
- * Allows for customization of emitting code, which is processed after
- * normal DataNodeContainer body. Ideal for augmentations or others.
- */
- protected void emitAfterBody(final StringBuilder sb) {
- // No-op
- }
-
- private static Map<String, Type> collectAllProperties(final GeneratedType type, final Map<String, Type> hashMap) {
- for (final MethodSignature definition : type.getMethodDefinitions()) {
- hashMap.put(definition.getName(), definition.getReturnType());
- }
- for (final Type parent : type.getImplements()) {
- if (parent instanceof GeneratedType) {
- collectAllProperties((GeneratedType) parent, hashMap);
- }
- }
- return hashMap;
- }
-
- private void emitBody(final StringBuilder sb) {
- final Map<String, Type> getterToType = collectAllProperties(dtoType, new HashMap<String, Type>());
- for (final DataSchemaNode schemaChild : schemaNode.getChildNodes()) {
- if (!schemaChild.isAugmenting()) {
- final String getter = BindingSchemaMapping.getGetterMethodName(schemaChild);
- final Type childType = getterToType.get(getter);
- checkState(childType != null, "Unable to find type for child node %s. Expected child nodes: %s",
- schemaChild.getPath(), getterToType);
- emitChild(sb, getter, childType, schemaChild);
- }
- }
- }
-
- private void emitChild(final StringBuilder sb, final String getterName, final Type childType,
- final DataSchemaNode schemaChild) {
- sb.append(statement(assign(childType, getterName, cast(childType, invoke(INPUT, getterName)))));
-
- sb.append("if (").append(getterName).append(" != null) {\n");
- emitChildInner(sb, getterName, childType, schemaChild);
- sb.append("}\n");
- }
-
- private void emitChildInner(final StringBuilder sb, final String getterName, final Type childType,
- final DataSchemaNode child) {
- if (child instanceof LeafSchemaNode) {
- sb.append(statement(leafNode(child.getQName().getLocalName(), getterName)));
- } else if (child instanceof AnyXmlSchemaNode) {
- sb.append(statement(anyxmlNode(child.getQName().getLocalName(), getterName)));
- } else if (child instanceof LeafListSchemaNode) {
- final CharSequence startEvent;
- if (((LeafListSchemaNode) child).isUserOrdered()) {
- startEvent = startOrderedLeafSet(child.getQName().getLocalName(),invoke(getterName, "size"));
- } else {
- startEvent = startLeafSet(child.getQName().getLocalName(),invoke(getterName, "size"));
- }
- sb.append(statement(startEvent));
- final Type valueType = ((ParameterizedType) childType).getActualTypeArguments()[0];
- sb.append(forEach(getterName, valueType, statement(leafSetEntryNode(CURRENT))));
- sb.append(statement(endNode()));
- } else if (child instanceof ListSchemaNode) {
- final Type valueType = ((ParameterizedType) childType).getActualTypeArguments()[0];
- final ListSchemaNode casted = (ListSchemaNode) child;
- emitList(sb, getterName, valueType, casted);
- } else if (child instanceof ContainerSchemaNode) {
- sb.append(tryToUseCacheElse(getterName, statement(staticInvokeEmitter(childType, getterName))));
- } else if (child instanceof ChoiceSchemaNode) {
- final String propertyName = CHOICE_PREFIX + childType.getName();
- staticConstant(propertyName, DataObjectSerializerImplementation.class,
- ChoiceDispatchSerializer.from(loadClass(childType)));
- sb.append(tryToUseCacheElse(getterName, statement(invoke(propertyName,
- StreamWriterGenerator.SERIALIZE_METHOD_NAME, REGISTRY, cast(DataObject.class, getterName), STREAM))));
- }
- }
-
- private static StringBuilder tryToUseCacheElse(final String getterName, final CharSequence statement) {
- return new StringBuilder()
- .append("if (").append(SERIALIZER).append(" == null || ")
- .append(invoke(SERIALIZER, "serialize", getterName)).append(" == null) {\n")
- .append(statement)
- .append('}');
- }
-
- private void emitList(final StringBuilder sb, final String getterName, final Type valueType,
- final ListSchemaNode child) {
- final CharSequence startEvent;
-
- sb.append(statement(assign("int", "_count", invoke(getterName, "size"))));
- if (child.getKeyDefinition().isEmpty()) {
- startEvent = startUnkeyedList(classReference(valueType), "_count");
- } else if (child.isUserOrdered()) {
- startEvent = startOrderedMapNode(classReference(valueType), "_count");
- } else {
- startEvent = startMapNode(classReference(valueType), "_count");
- }
- sb.append(statement(startEvent));
- sb.append(forEach(getterName, valueType, tryToUseCacheElse(CURRENT, statement(staticInvokeEmitter(valueType,
- CURRENT)))));
- sb.append(statement(endNode()));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. 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
- */
-package org.opendaylight.mdsal.binding.dom.codec.gen.impl;
-
-import org.opendaylight.mdsal.binding.generator.util.BindingRuntimeContext;
-import org.opendaylight.yangtools.yang.binding.DataObjectSerializerImplementation;
-
-/**
- * Public interface exposed from generator implementation.
- *
- * @deprecated This interface is superseded by an internal implementation.
- */
-@Deprecated
-public interface DataObjectSerializerGenerator {
- /**
- * Get a serializer for a particular type.
- *
- * @param type Type class
- * @return Serializer instance.
- */
- DataObjectSerializerImplementation getSerializer(Class<?> type);
-
- /**
- * Notify the generator that the runtime context has been updated.
- * @param runtime New runtime context
- */
- void onBindingRuntimeContextUpdated(BindingRuntimeContext runtime);
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. 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
- */
-package org.opendaylight.mdsal.binding.dom.codec.gen.impl;
-
-import org.opendaylight.yangtools.yang.binding.BindingStreamEventWriter;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.DataObjectSerializerImplementation;
-import org.opendaylight.yangtools.yang.binding.DataObjectSerializerRegistry;
-
-/**
- * Prototype of a DataObjectSerializerImplementation. This is a template class, which the
- * {@link AbstractStreamWriterGenerator} uses to instantiate {@link DataObjectSerializerImplementation} on a per-type
- * basis. During that time, the {@link #serialize(DataObjectSerializerRegistry, DataObject, BindingStreamEventWriter)}
- * method will be replaced by the real implementation.
- */
-@Deprecated
-final class DataObjectSerializerPrototype implements DataObjectSerializerImplementation {
- private static final DataObjectSerializerPrototype INSTANCE = new DataObjectSerializerPrototype();
-
- private DataObjectSerializerPrototype() {
- // Intentionally hidden, subclasses can replace it
- }
-
- /**
- * Return the shared serializer instance.
- *
- * @return Global singleton instance.
- */
- public static DataObjectSerializerPrototype getInstance() {
- return INSTANCE;
- }
-
- @Override
- public void serialize(final DataObjectSerializerRegistry reg, final DataObject obj,
- final BindingStreamEventWriter stream) {
- throw new UnsupportedOperationException("Prototype body, this code should never be invoked.");
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. 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
- */
-package org.opendaylight.mdsal.binding.dom.codec.gen.impl;
-
-import static java.util.Objects.requireNonNull;
-
-import org.opendaylight.mdsal.binding.dom.codec.gen.spi.AbstractSource;
-import org.opendaylight.mdsal.binding.generator.api.ClassLoadingStrategy;
-import org.opendaylight.mdsal.binding.generator.impl.GeneratedClassLoadingStrategy;
-import org.opendaylight.mdsal.binding.model.api.Type;
-import org.opendaylight.yangtools.yang.binding.BindingStreamEventWriter;
-import org.opendaylight.yangtools.yang.binding.DataContainer;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.DataObjectSerializerRegistry;
-
-@Deprecated
-abstract class DataObjectSerializerSource extends AbstractSource {
-
- private static final ClassLoadingStrategy STRATEGY = GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy();
-
- protected static final String SERIALIZER = "_serializer";
- protected static final String STREAM = "_stream";
- protected static final String ITERATOR = "_iterator";
- protected static final String CURRENT = "_current";
- protected static final String REGISTRY = "_registry";
-
- private final AbstractGenerator generator;
-
- /**
- * Create a new source.
- *
- * @param generator Parent generator
- */
- DataObjectSerializerSource(final AbstractGenerator generator) {
- this.generator = requireNonNull(generator);
- }
-
- @SuppressWarnings("unchecked")
- protected Class<? extends DataContainer> loadClass(final Type childType) {
- try {
- return (Class<? extends DataContainer>) STRATEGY.loadClass(childType);
- } catch (final ClassNotFoundException e) {
- throw new IllegalStateException("Could not load referenced class ", e);
- }
- }
-
- /**
- * Returns body of static serialize method.
- *
- * <ul>
- * <li> {@link DataObjectSerializerRegistry} - registry of serializers
- * <li> {@link DataObject} - object to be serialized
- * <li> {@link BindingStreamEventWriter} - writer to which events should be serialized.
- * </ul>
- *
- * @return Valid javassist code describing static serialization body.
- */
- protected abstract CharSequence getSerializerBody();
-
- // FIXME: 5.0.0: consider optimizing streaming use through returning StringBuilder from common methods
- protected static final CharSequence leafNode(final String localName, final CharSequence value) {
- return invoke(STREAM, "leafNode", escape(localName), value);
- }
-
- protected static final CharSequence startLeafSet(final String localName, final CharSequence expected) {
- return invoke(STREAM, "startLeafSet", escape(localName), expected);
- }
-
- protected static final CharSequence startOrderedLeafSet(final String localName, final CharSequence expected) {
- return invoke(STREAM, "startOrderedLeafSet", escape(localName), expected);
- }
-
- protected static final CharSequence leafSetEntryNode(final CharSequence value) {
- return invoke(STREAM, "leafSetEntryNode", value);
- }
-
- protected static final CharSequence startContainerNode(final CharSequence type, final CharSequence expected) {
- return invoke(STREAM, "startContainerNode", type, expected);
- }
-
- protected static final CharSequence escape(final String localName) {
- return '"' + localName + '"';
- }
-
- protected static final CharSequence startUnkeyedList(final CharSequence type, final CharSequence expected) {
- return invoke(STREAM, "startUnkeyedList", type, expected);
- }
-
- protected static final CharSequence startUnkeyedListItem(final CharSequence expected) {
- return invoke(STREAM, "startUnkeyedListItem", expected);
- }
-
- protected static final CharSequence startMapNode(final CharSequence type,final CharSequence expected) {
- return invoke(STREAM, "startMapNode", type, expected);
- }
-
- protected static final CharSequence startOrderedMapNode(final CharSequence type,final CharSequence expected) {
- return invoke(STREAM, "startOrderedMapNode", type, expected);
- }
-
- protected static final CharSequence startMapEntryNode(final CharSequence key, final CharSequence expected) {
- return invoke(STREAM, "startMapEntryNode", key, expected);
- }
-
- protected static final CharSequence startAugmentationNode(final CharSequence key) {
- return invoke(STREAM, "startAugmentationNode", key);
- }
-
- protected static final CharSequence startChoiceNode(final CharSequence localName, final CharSequence expected) {
- return invoke(STREAM, "startChoiceNode", localName, expected);
- }
-
- protected static final CharSequence startCaseNode(final CharSequence localName, final CharSequence expected) {
- return invoke(STREAM, "startCase", localName, expected);
- }
-
- protected static final CharSequence anyxmlNode(final String localName, final CharSequence value)
- throws IllegalArgumentException {
- return invoke(STREAM, "anyxmlNode", escape(localName), value);
- }
-
- protected static final CharSequence endNode() {
- return invoke(STREAM, "endNode");
- }
-
- protected static final CharSequence forEach(final String iterable,final Type valueType,final CharSequence body) {
- return forEach(iterable, ITERATOR, valueType.getFullyQualifiedName(), CURRENT, body);
- }
-
- protected static final CharSequence classReference(final Type type) {
- return type.getFullyQualifiedName() + ".class";
- }
-
- protected final CharSequence staticInvokeEmitter(final Type childType, final String name) {
- final Class<?> cls;
- try {
- cls = STRATEGY.loadClass(childType);
- } catch (final ClassNotFoundException e) {
- throw new IllegalStateException("Failed to invoke emitter", e);
- }
-
- final String className = this.generator.loadSerializerFor(cls) + ".getInstance()";
- return invoke(className, AbstractStreamWriterGenerator.SERIALIZE_METHOD_NAME, REGISTRY, name, STREAM);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. 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
- */
-package org.opendaylight.mdsal.binding.dom.codec.gen.impl;
-
-import org.opendaylight.mdsal.binding.dom.codec.util.AugmentableDispatchSerializer;
-import org.opendaylight.mdsal.binding.dom.codec.util.ChoiceDispatchSerializer;
-import org.opendaylight.mdsal.binding.generator.util.JavassistUtils;
-import org.opendaylight.mdsal.binding.model.api.GeneratedType;
-import org.opendaylight.mdsal.binding.spec.naming.BindingMapping;
-import org.opendaylight.yangtools.yang.binding.BindingStreamEventWriter;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.DataObjectSerializerImplementation;
-import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
-
-/**
- * Concrete implementation of {@link AbstractStreamWriterGenerator} which in runtime generates classes implementing
- * {@link DataObjectSerializerImplementation} interface and are used to serialize Binding {@link DataObject}.
- *
- * <p>
- * Actual implementation of codecs is done via static methods, which allows for static wiring of codecs. Choice codec
- * and Augmentable codecs are static properties of parent codec and stateless implementations are used
- * ({@link ChoiceDispatchSerializer}, {@link AugmentableDispatchSerializer}), which uses registry to dispatch to
- * concrete item codec.
- *
- * @deprecated This class is superseded by an internal implementation.
- */
-@Deprecated
-public final class StreamWriterGenerator extends AbstractStreamWriterGenerator {
- private static final String UNKNOWN_SIZE = BindingStreamEventWriter.class.getName() + ".UNKNOWN_SIZE";
-
- private StreamWriterGenerator(final JavassistUtils utils) {
- super(utils);
- }
-
- /**
- * Create a new instance backed by a specific {@link JavassistUtils} instance.
- *
- * @param utils JavassistUtils instance to use
- * @return A new generator
- */
- public static DataObjectSerializerGenerator create(final JavassistUtils utils) {
- return new StreamWriterGenerator(utils);
- }
-
- @Override
- protected DataObjectSerializerSource generateContainerSerializer(final GeneratedType type,
- final ContainerSchemaNode node) {
- return new AugmentableDataNodeContainerEmitterSource(this, type, node) {
- @Override
- public CharSequence emitStartEvent() {
- return startContainerNode(classReference(type), UNKNOWN_SIZE);
- }
- };
- }
-
- @Override
- protected DataObjectSerializerSource generateNotificationSerializer(final GeneratedType type,
- final NotificationDefinition node) {
- return new AugmentableDataNodeContainerEmitterSource(this, type, node) {
- @Override
- public CharSequence emitStartEvent() {
- return startContainerNode(classReference(type), UNKNOWN_SIZE);
- }
- };
- }
-
- @Override
- protected DataObjectSerializerSource generateCaseSerializer(final GeneratedType type, final CaseSchemaNode node) {
- return new AugmentableDataNodeContainerEmitterSource(this, type, node) {
- @Override
- public CharSequence emitStartEvent() {
- return startCaseNode(classReference(type),UNKNOWN_SIZE);
- }
- };
- }
-
- @Override
- protected DataObjectSerializerSource generateUnkeyedListEntrySerializer(final GeneratedType type,
- final ListSchemaNode node) {
- return new AugmentableDataNodeContainerEmitterSource(this, type, node) {
- @Override
- public CharSequence emitStartEvent() {
- return startUnkeyedListItem(UNKNOWN_SIZE);
- }
- };
- }
-
- @Override
- protected DataObjectSerializerSource generateSerializer(final GeneratedType type,
- final AugmentationSchemaNode schema) {
- return new DataNodeContainerSerializerSource(this, type, schema) {
- @Override
- public CharSequence emitStartEvent() {
- return startAugmentationNode(classReference(type));
- }
- };
- }
-
- @Override
- protected DataObjectSerializerSource generateMapEntrySerializer(final GeneratedType type,
- final ListSchemaNode node) {
- return new AugmentableDataNodeContainerEmitterSource(this, type, node) {
- @Override
- public CharSequence emitStartEvent() {
- return startMapEntryNode(invoke(INPUT, BindingMapping.IDENTIFIABLE_KEY_NAME), UNKNOWN_SIZE);
- }
- };
- }
-}
import org.opendaylight.mdsal.binding.dom.codec.api.BindingLazyContainerNode;
import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeWriterFactory;
-import org.opendaylight.mdsal.binding.dom.codec.gen.impl.DataObjectSerializerGenerator;
import org.opendaylight.mdsal.binding.dom.codec.util.AbstractBindingLazyContainerNode;
import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext;
import org.opendaylight.mdsal.binding.generator.util.BindingRuntimeContext;
BindingCodecTreeFactory, BindingNormalizedNodeWriterFactory, BindingNormalizedNodeSerializer {
private static final Logger LOG = LoggerFactory.getLogger(BindingNormalizedNodeCodecRegistry.class);
- private final DataObjectSerializerGenerator generator;
-
private static final AtomicReferenceFieldUpdater<BindingNormalizedNodeCodecRegistry, BindingCodecContext> UPDATER =
AtomicReferenceFieldUpdater.newUpdater(BindingNormalizedNodeCodecRegistry.class, BindingCodecContext.class,
"codecContext");
private volatile BindingCodecContext codecContext;
public BindingNormalizedNodeCodecRegistry() {
- this.generator = null;
+
}
public BindingNormalizedNodeCodecRegistry(final BindingRuntimeContext codecContext) {
onBindingRuntimeContextUpdated(codecContext);
}
- @Deprecated
- public BindingNormalizedNodeCodecRegistry(final DataObjectSerializerGenerator generator) {
- this.generator = requireNonNull(generator);
- }
-
@Override
public DataObjectSerializer getSerializer(final Class<? extends DataObject> type) {
return codecContext().getSerializer(type);
}
final BindingCodecContext updated = new BindingCodecContext(context, this);
- if (UPDATER.compareAndSet(this, current, updated)) {
- if (generator != null) {
- generator.onBindingRuntimeContextUpdated(context);
- }
- } else {
+ if (!UPDATER.compareAndSet(this, current, updated)) {
LOG.warn("Concurrent update of runtime context (expected={} current={}) detected at ", current,
codecContext, new Throwable());
}
<packaging>bundle</packaging>
<dependencies>
- <dependency>
- <groupId>org.javassist</groupId>
- <artifactId>javassist</artifactId>
- </dependency>
-
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-data-api</artifactId>
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. 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
- */
-package org.opendaylight.mdsal.binding.generator.util;
-
-import com.google.common.annotations.Beta;
-import javassist.CannotCompileException;
-import javassist.CtClass;
-import javassist.NotFoundException;
-
-/**
- * Interface allowing customization of classes after loading.
- *
- * @deprecated Code generation is a concert separate from type mapping and is an implementation detail.
- */
-@Beta
-@Deprecated
-@FunctionalInterface
-public interface ClassCustomizer {
- /**
- * Customize a class.
- *
- * @param cls Class to be customized
- * @throws CannotCompileException when a javassist error occurs
- * @throws NotFoundException when a javassist error occurs
- */
- void customizeClass(CtClass cls) throws CannotCompileException, NotFoundException;
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. 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
- */
-package org.opendaylight.mdsal.binding.generator.util;
-
-import javassist.CannotCompileException;
-import javassist.CtClass;
-
-@Deprecated
-public interface ClassGenerator {
- void process(CtClass cls) throws CannotCompileException;
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Brocade Communications Systems, Inc. and others. 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
- */
-package org.opendaylight.mdsal.binding.generator.util;
-
-import com.google.common.io.Files;
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import javassist.CtClass;
-import javassist.CtField;
-import javassist.CtMethod;
-import javassist.Modifier;
-import javassist.NotFoundException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The default implementation of the SourceCodeGenerator interface that generates readable source code
- * for a runtime generated class. The appendField/appendMethod methods output source code to a temporary
- * StringBuilder. When outputGeneratedSource is called, the entire class source code is generated and
- * written to a file under a specified directory.
- *
- * @author Thomas Pantelis
- *
- * @deprecated Code generation is a concert separate from type mapping and is an implementation detail.
- */
-@Deprecated
-public class DefaultSourceCodeGenerator implements SourceCodeGenerator {
- private static final Logger LOG = LoggerFactory.getLogger(DefaultSourceCodeGenerator.class);
-
- private static final String GENERATED_SOURCE_DIR_PROP = "org.opendaylight.yangtools.sal.generatedCodecSourceDir";
-
- private final StringBuilder builder = new StringBuilder();
- private final String generatedSourceDir;
-
- /**
- * Constructor.
- *
- * @param generatedSourceDir the directory in which to put generated source files. If null, the directory
- * is obtained from a system property (<i>org.opendaylight.yangtools.sal.generatedCodecSourceDir</i>) or
- * defaults to "generated-codecs".
- */
- public DefaultSourceCodeGenerator(final String generatedSourceDir) {
- if (generatedSourceDir != null) {
- this.generatedSourceDir = generatedSourceDir;
- } else {
- this.generatedSourceDir = System.getProperty(GENERATED_SOURCE_DIR_PROP, "generated-codecs");
- }
- }
-
- @Override
- public void appendField(final CtField field, final String value) {
- try {
- builder.append('\n')
- .append(Modifier.toString(field.getModifiers()))
- .append(' ').append(field.getType().getName()).append(' ')
- .append(field.getName());
- if (value != null) {
- builder.append(" = ").append(value);
- }
-
- builder.append(";\n");
- } catch (NotFoundException e) {
- LOG.error("Error building field source for {}", field.getName(), e);
- }
- }
-
- @Override
- public void appendMethod(final CtMethod method, final String code) {
- try {
- builder.append('\n')
- .append(Modifier.toString(method.getModifiers()))
- .append(' ').append(method.getReturnType().getName())
- .append(' ').append(method.getName()).append("( ");
-
- CtClass[] paramTypes = method.getParameterTypes();
- if (paramTypes != null) {
- for (int i = 0; i < paramTypes.length; i++) {
- if (i > 0) {
- builder.append(", ");
- }
- builder.append(paramTypes[i].getName()).append(" $")
- .append(i + 1);
- }
- }
-
- builder.append(" )\n").append(code).append("\n\n");
- } catch (NotFoundException e) {
- LOG.error("Error building method source for {}", method.getName(), e);
- }
- }
-
- @Override
- @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
- public void outputGeneratedSource(final CtClass ctClass) {
- String name = ctClass.getName();
-
- StringBuilder classBuilder = new StringBuilder();
- classBuilder.append(Modifier.toString(ctClass.getModifiers()))
- .append(" class ").append(ctClass.getSimpleName());
-
- try {
- CtClass superClass = ctClass.getSuperclass();
- if (superClass != null) {
- classBuilder.append(" extends ").append(superClass.getName());
- }
-
- CtClass[] interfaces = ctClass.getInterfaces();
- if (interfaces.length > 0) {
- classBuilder.append(" implements ");
- for (int i = 0; i < interfaces.length; i++) {
- if (i > 0) {
- classBuilder.append(", ");
- }
-
- classBuilder.append(interfaces[i].getName());
- }
- }
-
- classBuilder.append(" {\n").append(builder).append("\n}");
- } catch (NotFoundException e) {
- LOG.error("Error building class source for {}", name, e);
- return;
- }
-
- File dir = new File(generatedSourceDir);
- if (!dir.mkdir()) {
- LOG.warn("Failed to create directory {}, attempting to continue", generatedSourceDir);
- }
-
- try (BufferedWriter writer = Files.newWriter(new File(dir, name + ".java"), StandardCharsets.UTF_8)) {
- writer.append(classBuilder);
- writer.flush();
- } catch (IOException e) {
- LOG.error("Error writing class source for {}", name, e);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. 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
- */
-package org.opendaylight.mdsal.binding.generator.util;
-
-import javassist.CtField;
-
-@Deprecated
-public interface FieldGenerator {
- void process(CtField field);
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. 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
- */
-package org.opendaylight.mdsal.binding.generator.util;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.annotations.Beta;
-import java.util.Map;
-import java.util.WeakHashMap;
-import javassist.CannotCompileException;
-import javassist.ClassClassPath;
-import javassist.ClassPath;
-import javassist.ClassPool;
-import javassist.CtClass;
-import javassist.LoaderClassPath;
-import javassist.NotFoundException;
-import org.checkerframework.checker.lock.qual.GuardedBy;
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Users of this utility class are expected to synchronize on this instance it they need to ensure atomic operations
- * on it. Individual operations are synchronized and therefore are thread-safe.
- *
- * @deprecated This class has been deprecated due to not being quite able to work in multi-classloader environments
- * without holding strong central references.
- */
-@Deprecated
-@NonNullByDefault
-public final class JavassistUtils {
- private static final Logger LOG = LoggerFactory.getLogger(JavassistUtils.class);
- private static final Map<ClassPool, JavassistUtils> INSTANCES = new WeakHashMap<>();
-
- @GuardedBy("this")
- private final Map<ClassLoader, ClassPath> loaderClassPaths = new WeakHashMap<>();
- @GuardedBy("this")
- private final ClassPool classPool;
-
- private JavassistUtils(final ClassPool pool) {
- classPool = requireNonNull(pool);
- }
-
- /**
- * Get a utility instance for a particular class pool. A new instance is
- * created if this is a new pool. If an instance already exists, is is
- * returned.
- *
- * @param pool Backing class pool
- * @return shared utility instance for specified pool
- */
- public static synchronized JavassistUtils forClassPool(final ClassPool pool) {
- return INSTANCES.computeIfAbsent(requireNonNull(pool), JavassistUtils::new);
- }
-
- /**
- * Instantiate a new class based on a prototype. The class is set to automatically prune. The {@code customizer}
- * is guaranteed to run with this object locked.
- *
- * @param prototype Prototype class fully qualified name
- * @param fqn Target class fully qualified name
- * @param customizer Customization callback to be invoked on the new class
- * @return An instance of the new class
- * @throws NotFoundException when the prototype class is not found
- */
- @Beta
- @SuppressWarnings("checkstyle:illegalCatch")
- public synchronized CtClass instantiatePrototype(final String prototype, final String fqn,
- final ClassCustomizer customizer) throws CannotCompileException, NotFoundException {
- final CtClass result = classPool.getAndRename(prototype, fqn);
- try {
- customizer.customizeClass(result);
- } catch (CannotCompileException | NotFoundException e) {
- result.detach();
- throw e;
- } catch (Exception e) {
- LOG.warn("Failed to customize {} from prototype {}", fqn, prototype, e);
- result.detach();
- throw new IllegalStateException(String.format("Failed to instantiate prototype %s as %s", prototype, fqn),
- e);
- }
-
- result.stopPruning(false);
- return result;
- }
-
- @GuardedBy("this")
- public CtClass asCtClass(final Class<?> cls) {
- try {
- return classPool.get(cls.getName());
- } catch (NotFoundException nfe1) {
- appendClassLoaderIfMissing(cls.getClassLoader());
- try {
- return classPool.get(cls.getName());
- } catch (final NotFoundException nfe2) {
- LOG.warn("Appending ClassClassPath for {}", cls, nfe2);
- classPool.appendClassPath(new ClassClassPath(cls));
- try {
- return classPool.get(cls.getName());
- } catch (NotFoundException e) {
- LOG.warn("Failed to load class {} from pool {}", cls, classPool, e);
- throw new IllegalStateException("Failed to load class", e);
- }
- }
- }
- }
-
- public synchronized void appendClassLoaderIfMissing(final ClassLoader loader) {
- if (!loaderClassPaths.containsKey(loader)) {
- final ClassPath ctLoader = new LoaderClassPath(loader);
- classPool.appendClassPath(ctLoader);
- loaderClassPaths.put(loader, ctLoader);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Brocade Communications Systems, Inc. and others. 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
- */
-package org.opendaylight.mdsal.binding.generator.util;
-
-import javassist.CtClass;
-import javassist.CtField;
-import javassist.CtMethod;
-
-/**
- * Implementation of the SourceCodeGenerator interface that does nothing.
- *
- * @author Thomas Pantelis
- */
-@Deprecated
-public class NullSourceCodeGenerator implements SourceCodeGenerator {
-
- @Override
- public void appendField(final CtField field, final String value) {
- }
-
- @Override
- public void appendMethod(final CtMethod method, final String code) {
- }
-
- @Override
- public void outputGeneratedSource(final CtClass ctClass) {
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Brocade Communications Systems, Inc. and others. 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
- */
-package org.opendaylight.mdsal.binding.generator.util;
-
-import javassist.CtClass;
-import javassist.CtField;
-import javassist.CtMethod;
-
-/**
- * Interface for a class that that generates readable source code for a runtime generated class.
- * The appendField/appendMethod methods append source code to a temporary output. When outputGeneratedSource
- * is called, the entire class source code is generated and outputted.
- *
- * @author Thomas Pantelis
- * @deprecated Code generation is a concert separate from type mapping and is an implementation detail. Most notably
- * there may actually not be intermediate source code.
- */
-@Deprecated
-public interface SourceCodeGenerator {
-
- /**
- * Appends the given class field and value to the temporary output.
- */
- void appendField(CtField field, String value);
-
- /**
- * Appends the given method and source code body to the temporary output.
- */
- void appendMethod(CtMethod method, String code);
-
- /**
- * Generates the full source code for the given class and outputs it.
- */
- void outputGeneratedSource(CtClass ctClass);
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014 Brocade Communications Systems, Inc. and others. 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
- */
-package org.opendaylight.mdsal.binding.generator.util;
-
-/**
- * Factory class for creating SourceCodeGenerator instances.
- *
- * @author Thomas Pantelis
- * @deprecated Code generation is a concert separate from type mapping and is an implementation detail.
- */
-@Deprecated
-public class SourceCodeGeneratorFactory {
-
- private static final String GENERATE_CODEC_SOURCE_PROP = "org.opendaylight.yangtools.sal.generateCodecSource";
-
- private static final SourceCodeGenerator NULL_GENERATOR = new NullSourceCodeGenerator();
-
- /**
- * Gets a SourceCodeGenerator instance.
- *
- * <p>
- * Generation of source code is controlled by the <i>org.opendaylight.yangtools.sal.generateCodecSource</i>
- * system property. If set to true, a DefaultSourceCodeGenerator instance is returned, otherwise a
- * NullSourceCodeGenerator is returned.
- *
- * @param generatedSourceDir the directory in which to put generated source files. If null,
- * a default is used (see DefaultSourceCodeGenerator).
- */
- public SourceCodeGenerator getInstance(final String generatedSourceDir) {
- boolean generateSource = Boolean.getBoolean(GENERATE_CODEC_SOURCE_PROP);
- if (generateSource) {
- return new DefaultSourceCodeGenerator(generatedSourceDir);
- }
-
- return NULL_GENERATOR;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. 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
- */
-package org.opendaylight.mdsal.binding.generator.util;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.mock;
-
-import javassist.CannotCompileException;
-import javassist.ClassPool;
-import javassist.NotFoundException;
-import org.junit.Test;
-
-@Deprecated
-public class JavassistUtilsTest {
-
- @Test
- public void forClassPool() throws CannotCompileException, NotFoundException {
- final JavassistUtils javassistUtils = JavassistUtils.forClassPool(ClassPool.getDefault());
- final ClassGenerator classGenerator = mock(ClassGenerator.class);
- doNothing().when(classGenerator).process(any());
-
- final ClassCustomizer classCustomizer = mock(ClassCustomizer.class);
- doNothing().when(classCustomizer).customizeClass(any());
- assertNotNull(javassistUtils.instantiatePrototype("javassist.CtNewClass", "leWut", classCustomizer));
- }
-
- @Test
- public void privateConstructTest() throws Exception {
- assertFalse(JavassistUtils.class.getDeclaredConstructor(ClassPool.class).isAccessible());
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. 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
- */
-package org.opendaylight.mdsal.binding.generator.util;
-
-import static java.util.Arrays.stream;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.CALLS_REAL_METHODS;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
-import com.google.common.collect.ImmutableList;
-import java.io.File;
-import java.lang.reflect.Field;
-import javassist.ClassPool;
-import javassist.CtClass;
-import javassist.CtField;
-import javassist.CtMethod;
-import javassist.bytecode.AccessFlag;
-import javassist.bytecode.ClassFile;
-import org.junit.Test;
-
-@Deprecated
-public class SourceCodeGeneratorFactoryTest {
-
- private static final SourceCodeGeneratorFactory FACTORY = new SourceCodeGeneratorFactory();
- private SourceCodeGenerator generator;
- private String propKey;
-
- @Test
- public void basicFactoryTest() throws Exception {
- final Field propField = SourceCodeGeneratorFactory.class.getDeclaredField("GENERATE_CODEC_SOURCE_PROP");
- propField.setAccessible(true);
- propKey = (String) propField.get(FACTORY);
- final String propValue;
- final boolean present;
-
- propValue = System.getProperty(propKey, null);
- present = propValue != null;
-
- testWithPropertyPresent();
- testWithoutPropertyPresent();
-
- if (present) {
- System.setProperty(propKey, propValue);
- } else {
- System.clearProperty(propKey);
- }
- }
-
- private void testWithPropertyPresent() throws Exception {
- System.clearProperty(propKey);
- System.setProperty(propKey, "true");
- generator = FACTORY.getInstance(null);
- assertTrue(generator instanceof DefaultSourceCodeGenerator);
- }
-
- private void testWithoutPropertyPresent() throws Exception {
- System.clearProperty(propKey);
- generator = FACTORY.getInstance(null);
- assertTrue(generator instanceof NullSourceCodeGenerator);
- }
-
- @Test
- public void nullSourceCodeGenTest() throws Exception {
- generator = new NullSourceCodeGenerator();
- generator.appendField(null, null);
- }
-
- @Test
- public void defaultSourceCodeGenTest() throws Exception {
- final File dir = new File("testDir");
- assertTrue(cleanup(dir));
-
- generator = new DefaultSourceCodeGenerator(dir.getName());
- final CtClass ctClass = mock(CtClass.class, CALLS_REAL_METHODS);
- doReturn(Boolean.FALSE).when(ctClass).isFrozen();
- ctClass.setName("TestClass");
- final ClassPool classPool = mock(ClassPool.class);
- doReturn(ctClass).when(classPool).get((String) any());
- doNothing().when(ctClass).setName("TestClass");
- doReturn(ctClass).when(ctClass).getSuperclass();
- doReturn(new CtClass[] {ctClass,ctClass}).when(ctClass).getInterfaces();
- doReturn(classPool).when(ctClass).getClassPool();
- doReturn(Boolean.FALSE).when(ctClass).isArray();
- doReturn(Boolean.FALSE).when(ctClass).isPrimitive();
- doReturn(AccessFlag.toModifier(AccessFlag.PUBLIC)).when(ctClass).getModifiers();
- final ClassFile classFile = new ClassFile(false,"test", null);
- doReturn(classFile).when(ctClass).getClassFile2();
- doReturn(Boolean.FALSE).when(ctClass).isFrozen();
- doReturn("testClass").when(ctClass).getName();
- final CtField ctField = mock(CtField.class);
- doReturn(AccessFlag.toModifier(AccessFlag.PUBLIC)).when(ctField).getModifiers();
- doReturn(ctClass).when(ctField).getType();
- doReturn("testField").when(ctField).getName();
- final CtMethod ctMethod = new CtMethod(ctClass,"method", new CtClass[] { ctClass , ctClass }, ctClass);
-
- generator.appendField(ctField, "b");
- generator.appendMethod(ctMethod, "c");
- generator.outputGeneratedSource(ctClass);
-
- assertTrue(dir.exists());
- assertTrue(dir.isDirectory());
- assertFalse(ImmutableList.of(dir.listFiles()).isEmpty());
-
- assertTrue(cleanup(dir));
- }
-
- private static boolean cleanup(final File dir) {
- if (!dir.exists()) {
- return true;
- }
-
- stream(dir.listFiles()).forEach(File::delete);
- return dir.delete();
- }
-}
<description>MD-SAL Java Binding runtime</description>
<dependencies>
- <dependency>
- <groupId>org.opendaylight.odlparent</groupId>
- <artifactId>odl-javassist-3</artifactId>
- <type>xml</type>
- <classifier>features</classifier>
- </dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>odl-yangtools-data</artifactId>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<features xmlns="http://karaf.apache.org/xmlns/features/v1.4.0" name="odl-mdsal-binding-runtime">
<feature name="odl-mdsal-binding-runtime">
- <feature version="[5,6)">odl-javassist-3</feature>
<feature version="[3,4)">odl-yangtools-data</feature>
<feature version="[3,4)">odl-yangtools-parser</feature>
</feature>