2 * Copyright (c) 2013 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.controller.config.yangjmxgenerator;
10 import static com.google.common.base.Preconditions.checkNotNull;
11 import static java.lang.String.format;
12 import static org.opendaylight.controller.config.yangjmxgenerator.ConfigConstants.SERVICE_TYPE_Q_NAME;
14 import java.util.ArrayList;
15 import java.util.HashMap;
16 import java.util.HashSet;
17 import java.util.Iterator;
18 import java.util.List;
22 import org.opendaylight.yangtools.yang.common.QName;
23 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
24 import org.opendaylight.yangtools.yang.model.api.Module;
25 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
29 import com.google.common.base.Optional;
32 * Represents identity derived from {@link ConfigConstants#SERVICE_TYPE_Q_NAME}.
40 * "Service representing an event bus. The service acts as message
41 * router between event producers and event consumers";
43 * base "config:service-type";
44 * config:java-class "com.google.common.eventbus.EventBus";
51 public class ServiceInterfaceEntry extends AbstractEntry {
52 private static final Logger logger = LoggerFactory
53 .getLogger(ServiceInterfaceEntry.class);
55 private static final String CLASS_NAME_SUFFIX = "ServiceInterface";
56 private final Optional<ServiceInterfaceEntry> maybeBaseCache;
57 private final String exportedOsgiClassName;
58 private final QName qName;
59 private final String nullableDescription, packageName, typeName;
61 private ServiceInterfaceEntry(IdentitySchemaNode id, String packageName) {
62 this(Optional.<ServiceInterfaceEntry> absent(), id, packageName);
65 private ServiceInterfaceEntry(Optional<ServiceInterfaceEntry> base,
66 IdentitySchemaNode id, String packageName) {
68 this.maybeBaseCache = base;
69 List<UnknownSchemaNode> unknownSchemaNodes = id.getUnknownSchemaNodes();
70 List<String> exportedOsgiClassNames = new ArrayList<>(
71 unknownSchemaNodes.size());
72 for (UnknownSchemaNode usn : unknownSchemaNodes) {
73 if (ConfigConstants.JAVA_CLASS_EXTENSION_QNAME.equals(usn
75 String localName = usn.getNodeParameter();
76 exportedOsgiClassNames.add(localName);
78 throw new IllegalStateException(format(
79 "Unexpected unknown schema node. Expected %s, got %s",
80 ConfigConstants.JAVA_CLASS_EXTENSION_QNAME,
84 if (exportedOsgiClassNames.size() != 1) {
85 throw new IllegalArgumentException(
86 format("Cannot find one to one mapping from %s to "
87 + "java class defined by %s language extension in %s",
89 ConfigConstants.JAVA_CLASS_EXTENSION_QNAME, id));
91 this.exportedOsgiClassName = exportedOsgiClassNames.get(0);
92 qName = id.getQName();
93 nullableDescription = id.getDescription();
94 typeName = getSimpleName(exportedOsgiClassName) + CLASS_NAME_SUFFIX;
95 this.packageName = packageName;
98 private static final String getSimpleName(String fullyQualifiedName) {
99 int lastDotPosition = fullyQualifiedName.lastIndexOf(".");
100 return fullyQualifiedName.substring(lastDotPosition + 1);
103 public String getNullableDescription() {
104 return nullableDescription;
107 public Optional<ServiceInterfaceEntry> getBase() {
108 return maybeBaseCache;
111 public String getExportedOsgiClassName() {
112 return exportedOsgiClassName;
115 public QName getQName() {
120 * @return Map of QNames as keys and ServiceInterfaceEntry instances as
123 public static Map<QName, ServiceInterfaceEntry> create(Module module,
124 String packageName) {
125 logger.debug("Generating ServiceInterfaces from {} to package {}",
126 module.getNamespace(), packageName);
128 Map<IdentitySchemaNode, ServiceInterfaceEntry> identitiesToSIs = new HashMap<>();
129 Set<IdentitySchemaNode> notVisited = new HashSet<>(
130 module.getIdentities());
131 int lastSize = notVisited.size() + 1;
132 while (notVisited.size() > 0) {
133 if (notVisited.size() == lastSize) {
135 "Following identities will be ignored while generating ServiceInterfaces, as they are not derived from {} : {}",
136 SERVICE_TYPE_Q_NAME, notVisited);
139 lastSize = notVisited.size();
140 for (Iterator<IdentitySchemaNode> iterator = notVisited.iterator(); iterator
142 IdentitySchemaNode identity = iterator.next();
143 ServiceInterfaceEntry created = null;
144 if (identity.getBaseIdentity() == null) {
145 // this can happen while loading config module, just skip
148 } else if (identity.getBaseIdentity().getQName()
149 .equals(SERVICE_TYPE_Q_NAME)) {
150 // this is a base type
151 created = new ServiceInterfaceEntry(identity, packageName);
153 ServiceInterfaceEntry foundBase = identitiesToSIs
154 .get(identity.getBaseIdentity());
155 // derived type, did we convert the parent?
156 if (foundBase != null) {
157 created = new ServiceInterfaceEntry(
158 Optional.of(foundBase), identity, packageName);
161 if (created != null) {
162 created.setYangModuleName(module.getName());
163 // TODO how to get local name
164 created.setYangModuleLocalname(identity.getQName()
166 identitiesToSIs.put(identity, created);
172 Map<QName, ServiceInterfaceEntry> resultMap = new HashMap<>();
173 for (ServiceInterfaceEntry sie : identitiesToSIs.values()) {
174 resultMap.put(sie.getQName(), sie);
176 logger.debug("Number of ServiceInterfaces to be generated: {}",
181 public String getFullyQualifiedName() {
182 return packageName + "." + typeName;
185 public String getPackageName() {
189 public String getTypeName() {
194 public boolean equals(Object o) {
197 if (o == null || getClass() != o.getClass())
200 ServiceInterfaceEntry that = (ServiceInterfaceEntry) o;
202 if (!maybeBaseCache.equals(that.maybeBaseCache))
204 if (!nullableDescription.equals(that.nullableDescription))
206 if (!exportedOsgiClassName.equals(that.exportedOsgiClassName))
208 if (!qName.equals(that.qName))
210 if (!packageName.equals(that.packageName))
212 if (!typeName.equals(that.typeName))
219 public int hashCode() {
220 int result = maybeBaseCache.hashCode();
221 result = 31 * result + exportedOsgiClassName.hashCode();
222 result = 31 * result + nullableDescription.hashCode();
223 result = 31 * result + typeName.hashCode();
224 result = 31 * result + packageName.hashCode();
225 result = 31 * result + qName.hashCode();
230 public String toString() {
231 return "ServiceInterfaceEntry{" + "maybeBaseCache=" + maybeBaseCache
232 + ", qName='" + qName + '\'' + ", fullyQualifiedName='"
233 + getFullyQualifiedName() + '\'' + ", exportedOsgiClassName="
234 + exportedOsgiClassName + ", nullableDescription='"
235 + nullableDescription + '\'' + '}';