*/
package org.opendaylight.netconf.sal.restconf.impl;
-import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import java.io.Closeable;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+import javax.inject.Singleton;
import javax.ws.rs.core.Response.Status;
+import org.apache.aries.blueprint.annotation.service.Reference;
import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation;
import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
-import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
-import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.mdsal.dom.api.DOMMountPoint;
+import org.opendaylight.mdsal.dom.api.DOMMountPointService;
+import org.opendaylight.mdsal.dom.api.DOMSchemaService;
import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider;
import org.opendaylight.netconf.sal.rest.api.Draft02;
import org.opendaylight.netconf.sal.rest.api.Draft02.RestConfModule;
import org.opendaylight.restconf.common.errors.RestconfError.ErrorType;
import org.opendaylight.restconf.common.util.RestUtil;
import org.opendaylight.yangtools.concepts.Codec;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.Revision;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class ControllerContext implements SchemaContextListener {
+@Singleton
+public final class ControllerContext implements SchemaContextListener, Closeable {
// FIXME: this should be in md-sal somewhere
public static final String MOUNT = "yang-ext:mount";
private static final Logger LOG = LoggerFactory.getLogger(ControllerContext.class);
- // FIXME: this should be the current instance which is mutated
- private static final ControllerContext INSTANCE = new ControllerContext();
-
private static final String NULL_VALUE = "null";
private static final String MOUNT_MODULE = "yang-ext";
private final AtomicReference<Map<QName, RpcDefinition>> qnameToRpc = new AtomicReference<>(Collections.emptyMap());
- // FIXME; these three should be final
+ private final DOMMountPointService mountService;
+ private final DOMYangTextSourceProvider yangTextSourceProvider;
+ private final ListenerRegistration<SchemaContextListener> listenerRegistration;
private volatile SchemaContext globalSchema;
- private volatile DOMMountPointService mountService;
- private volatile DOMYangTextSourceProvider yangTextSourceProvider;
- private DataNormalizer dataNormalizer;
-
-
- public void setGlobalSchema(final SchemaContext globalSchema) {
- this.globalSchema = globalSchema;
- this.dataNormalizer = new DataNormalizer(globalSchema);
- }
+ private volatile DataNormalizer dataNormalizer;
- public void setMountService(final DOMMountPointService mountService) {
+ @Inject
+ public ControllerContext(final @Reference DOMSchemaService schemaService,
+ final @Reference DOMMountPointService mountService, final @Reference DOMSchemaService domSchemaService) {
this.mountService = mountService;
- }
+ this.yangTextSourceProvider = domSchemaService.getExtensions().getInstance(DOMYangTextSourceProvider.class);
- public DOMYangTextSourceProvider getYangTextSourceProvider() {
- return yangTextSourceProvider;
+ onGlobalContextUpdated(schemaService.getGlobalContext());
+ listenerRegistration = schemaService.registerSchemaContextListener(this);
}
- public void setYangTextSourceProvider(DOMYangTextSourceProvider yangTextSourceProvider) {
- this.yangTextSourceProvider = yangTextSourceProvider;
+ /**
+ * Factory method.
+ *
+ * @deprecated Just use the
+ * {@link #ControllerContext(DOMSchemaService, DOMMountPointService, DOMSchemaService)}
+ * constructor instead.
+ */
+ @Deprecated
+ public static ControllerContext newInstance(final DOMSchemaService schemaService,
+ final DOMMountPointService mountService, final DOMSchemaService domSchemaService) {
+ return new ControllerContext(schemaService, mountService, domSchemaService);
}
- ControllerContext() {
-
+ private void setGlobalSchema(final SchemaContext globalSchema) {
+ this.globalSchema = globalSchema;
+ this.dataNormalizer = new DataNormalizer(globalSchema);
}
- public static ControllerContext getInstance() {
- return INSTANCE;
+ public DOMYangTextSourceProvider getYangTextSourceProvider() {
+ return yangTextSourceProvider;
}
private void checkPreconditions() {
}
}
+ @Override
+ @PreDestroy
+ public void close() {
+ listenerRegistration.close();
+ }
+
public void setSchemas(final SchemaContext schemas) {
onGlobalContextUpdated(schemas);
}
return childByQName((Module) container, name);
} else {
throw new IllegalArgumentException("Unhandled parameter types: "
- + Arrays.<Object>asList(container, name).toString());
+ + Arrays.asList(container, name).toString());
}
}
return ret;
}
- private static String toUriString(final Object object, final LeafSchemaNode leafNode, final DOMMountPoint mount)
+ private String toUriString(final Object object, final LeafSchemaNode leafNode, final DOMMountPoint mount)
throws UnsupportedEncodingException {
- final Codec<Object, Object> codec = RestCodec.from(leafNode.getType(), mount);
+ final Codec<Object, Object> codec = RestCodec.from(leafNode.getType(), mount, this);
// FIXME: UrlEncoder looks up a well-known charset, we need something that will use it directly
return object == null ? "" : URLEncoder.encode(codec.serialize(object).toString(), URI_ENCODING_CHARSET.name());
}
private InstanceIdentifierContext<?> collectPathArguments(final InstanceIdentifierBuilder builder,
final List<String> strings, final DataNodeContainer parentNode, final DOMMountPoint mountPoint,
final boolean returnJustMountPoint) {
- Preconditions.<List<String>>checkNotNull(strings);
+ Preconditions.checkNotNull(strings);
if (parentNode == null) {
return null;
}
final String head = strings.iterator().next();
+
+ if (head.isEmpty()) {
+ final List<String> remaining = strings.subList(1, strings.size());
+ return collectPathArguments(builder, remaining, parentNode, mountPoint, returnJustMountPoint);
+ }
+
final String nodeName = toNodeName(head);
final String moduleName = toModuleName(head);
if (targetNode == null && parentNode instanceof Module) {
final RpcDefinition rpc;
if (mountPoint == null) {
- rpc = ControllerContext.getInstance().getRpcDefinition(head, module.getRevision());
+ rpc = getRpcDefinition(head, module.getRevision());
} else {
final String rpcName = toNodeName(head);
- ControllerContext.getInstance();
- rpc = ControllerContext.getRpcDefinition(module, rpcName);
+ rpc = getRpcDefinition(module, rpcName);
}
if (rpc != null) {
return new InstanceIdentifierContext<>(builder.build(), rpc, mountPoint,
if (baseType instanceof LeafrefTypeDefinition) {
typedef = SchemaContextUtil.getBaseTypeForLeafRef((LeafrefTypeDefinition) baseType, schemaContext, node);
}
- final Codec<Object, Object> codec = RestCodec.from(typedef, mountPoint);
+ final Codec<Object, Object> codec = RestCodec.from(typedef, mountPoint, this);
Object decoded = codec.deserialize(urlDecoded);
String additionalInfo = "";
if (decoded == null) {
public DataNormalizationOperation<?> getRootOperation() {
return this.dataNormalizer.getRootOperation();
}
-
}