2 * Copyright (c) 2018 Pantheon Technologies, s.r.o. 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.mdsal.binding.java.api.generator;
10 import static com.google.common.base.Verify.verify;
11 import static java.util.Objects.requireNonNull;
13 import com.google.common.collect.ImmutableList;
14 import java.util.ArrayDeque;
15 import java.util.Deque;
16 import java.util.Iterator;
17 import java.util.List;
18 import java.util.Optional;
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.opendaylight.mdsal.binding.model.api.GeneratedType;
22 import org.opendaylight.mdsal.binding.model.api.JavaTypeName;
25 * A type which is nested inside some other type. It defers import decisions to its enclosing type, eventually arriving
26 * at a {@link TopLevelJavaGeneratedType}.
28 * @author Robert Varga
31 final class NestedJavaGeneratedType extends AbstractJavaGeneratedType {
32 private final AbstractJavaGeneratedType enclosingType;
34 NestedJavaGeneratedType(final AbstractJavaGeneratedType enclosingType, final GeneratedType genType) {
36 this.enclosingType = requireNonNull(enclosingType);
40 boolean importCheckedType(final JavaTypeName type) {
41 // Defer to enclosing type, which needs to re-run its checks
42 return enclosingType.checkAndImportType(type);
46 String localTypeName(final JavaTypeName type) {
47 // Check if the type is a reference to our immediately-enclosing type
48 if (enclosingType.getName().equals(type)) {
49 return enclosingType.getSimpleName();
52 final @Nullable List<String> descendant = findDescandantPath(type);
53 if (descendant == null) {
54 // The type is not present in our hierarchy, defer to our immediately-enclosing type, which may be able
55 // to find the target.
56 return enclosingType.localTypeName(type);
59 // Target type is a declared as a enclosed type of us and we have the path where it lurks.
60 final Iterator<String> it = descendant.iterator();
61 final StringBuilder sb = new StringBuilder().append(it.next());
62 while (it.hasNext()) {
63 sb.append('.').append(it.next());
68 private @Nullable List<String> findDescandantPath(final JavaTypeName type) {
69 Optional<JavaTypeName> optEnclosing = type.immediatelyEnclosingClass();
70 verify(optEnclosing.isPresent());
72 final Deque<String> queue = new ArrayDeque<>();
73 queue.addFirst(type.simpleName());
74 while (optEnclosing.isPresent()) {
75 final JavaTypeName enclosing = optEnclosing.get();
76 if (enclosing.equals(getName())) {
77 return ImmutableList.copyOf(queue);
80 queue.addFirst(enclosing.simpleName());
81 optEnclosing = enclosing.immediatelyEnclosingClass();