- private NotificationCodecContext<?> createNotificationDataContext(final Class<?> notificationType) {
- Preconditions.checkArgument(Notification.class.isAssignableFrom(notificationType));
- Preconditions.checkArgument(notificationType.isInterface(), "Supplied class must be interface.");
- final QName qname = BindingReflections.findQName(notificationType);
- /**
- * FIXME: After Lithium cleanup of yang-model-api, use direct call on schema context
- * to retrieve notification via index.
- */
- final NotificationDefinition schema = SchemaContextUtil.getNotificationSchema(getSchema(),
- SchemaPath.create(true, qname));
- Preconditions.checkArgument(schema != null, "Supplied %s is not valid notification", notificationType);
-
- return new NotificationCodecContext<>(notificationType, schema, factory());
+ private ActionCodecContext prepareActionContext(final int inputOffset, final int outputOffset,
+ final int expectedArgsLength, final Class<? extends Action<?, ?, ?>> action, final Class<?> actionType) {
+ final Optional<ParameterizedType> optParamType = ClassLoaderUtils.findParameterizedType(action, actionType);
+ checkState(optParamType.isPresent(), "%s does not specialize %s", action, actionType);
+
+ final ParameterizedType paramType = optParamType.get();
+ final Type[] args = paramType.getActualTypeArguments();
+ checkArgument(args.length == expectedArgsLength, "Unexpected (%s) Action generatic arguments", args.length);
+ final ActionRuntimeType schema = factory().getRuntimeContext().getActionDefinition(action);
+ return new ActionCodecContext(
+ DataContainerCodecPrototype.from(asClass(args[inputOffset], RpcInput.class), schema.input(),
+ factory()).get(),
+ DataContainerCodecPrototype.from(asClass(args[outputOffset], RpcOutput.class), schema.output(),
+ factory()).get());
+ }
+
+ private static <T extends DataObject> Class<? extends T> asClass(final Type type, final Class<T> target) {
+ verify(type instanceof Class, "Type %s is not a class", type);
+ return ((Class<?>) type).asSubclass(target);
+ }
+
+ /**
+ * Returns RPC input or output schema based on supplied QName.
+ *
+ * @param rpc RPC Definition
+ * @param qname input or output QName with namespace same as RPC
+ * @return input or output schema. Returns null if RPC does not have input/output specified.
+ */
+ private static @Nullable ContainerLike getRpcDataSchema(final @NonNull RpcDefinition rpc,
+ final @NonNull QName qname) {
+ requireNonNull(rpc, "Rpc Schema must not be null");
+ switch (requireNonNull(qname, "QName must not be null").getLocalName()) {
+ case "input":
+ return rpc.getInput();
+ case "output":
+ return rpc.getOutput();
+ default:
+ throw new IllegalArgumentException("Supplied qname " + qname
+ + " does not represent rpc input or output.");
+ }
+ }
+
+ ChoiceNodeCodecContext<?> createChoiceDataContext(final Class<? extends DataObject> caseType) {
+ final Class<?> choiceClass = findCaseChoice(caseType);
+ checkArgument(choiceClass != null, "Class %s is not a valid case representation", caseType);
+ final CompositeRuntimeType schema = factory().getRuntimeContext().getSchemaDefinition(choiceClass);
+ checkArgument(schema instanceof ChoiceRuntimeType, "Class %s does not refer to a choice", caseType);
+
+ final DataContainerCodecContext<?, ChoiceRuntimeType> choice = DataContainerCodecPrototype.from(choiceClass,
+ (ChoiceRuntimeType)schema, factory()).get();
+ Verify.verify(choice instanceof ChoiceNodeCodecContext);
+ return (ChoiceNodeCodecContext<?>) choice;