2 * Copyright (c) 2014 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/eplv10.html
8 package org.opendaylight.yangtools.yang.model.repo.util;
10 import com.google.common.base.Optional;
11 import com.google.common.collect.HashMultimap;
12 import com.google.common.collect.Multimap;
13 import com.google.common.util.concurrent.AsyncFunction;
14 import com.google.common.util.concurrent.Futures;
15 import com.google.common.util.concurrent.ListenableFuture;
17 import java.util.ArrayList;
18 import java.util.Collection;
19 import java.util.Collections;
20 import java.util.Comparator;
21 import java.util.HashMap;
22 import java.util.Iterator;
23 import java.util.List;
26 import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory;
27 import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository;
28 import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceFilter;
29 import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
30 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
31 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider;
32 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistration;
33 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
34 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceTransformationException;
35 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceTransformer;
36 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaTransformerRegistration;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
40 public class AbstractSchemaRepository implements SchemaRepository, SchemaSourceRegistry {
41 private static final Logger LOG = LoggerFactory.getLogger(AbstractSchemaRepository.class);
42 private static final Comparator<SchemaTransformerRegistration> TRANSFORMER_COST_COMPARATOR = new Comparator<SchemaTransformerRegistration>() {
44 public int compare(final SchemaTransformerRegistration o1, final SchemaTransformerRegistration o2) {
45 return o1.getInstance().getCost() - o2.getInstance().getCost();
50 * Output-type -> transformer map. Our usage involves knowing the destination type,
51 * so we have to work backwards and find a transformer chain which will get us
52 * to that representation given our available sources.
54 private final Multimap<Class<? extends SchemaSourceRepresentation>, SchemaTransformerRegistration> transformers =
55 HashMultimap.create();
58 * Source identifier -> representation -> provider map. We usually are looking for
59 * a specific representation a source.
61 private final Map<SourceIdentifier, Multimap<Class<?>, AbstractSchemaSourceRegistration>> sources = new HashMap<>();
64 private static final <T extends SchemaSourceRepresentation> ListenableFuture<Optional<T>> fetchSource(final SourceIdentifier id, final Iterator<AbstractSchemaSourceRegistration> it) {
66 return Futures.immediateFuture(Optional.<T>absent());
69 return Futures.transform(((SchemaSourceProvider<T>)it.next().getProvider()).getSource(id), new AsyncFunction<Optional<T>, Optional<T>>() {
71 public ListenableFuture<Optional<T>> apply(final Optional<T> input) throws Exception {
72 if (input.isPresent()) {
73 return Futures.immediateFuture(input);
75 return fetchSource(id, it);
81 private <T extends SchemaSourceRepresentation> ListenableFuture<Optional<T>> transformSchemaSource(final SourceIdentifier id, final Class<T> representation) {
82 final Multimap<Class<?>, AbstractSchemaSourceRegistration> srcs = sources.get(id);
84 return Futures.immediateFailedFuture(new SchemaSourceTransformationException(
85 String.format("No providers producing a representation of %s registered", id)));
88 final Collection<SchemaTransformerRegistration> ts = transformers.get(representation);
90 return Futures.immediateFailedFuture(new SchemaSourceTransformationException(
91 String.format("No transformers producing representation %s registered", representation)));
94 // Build up the candidate list
95 final List<SchemaTransformerRegistration> candidates = new ArrayList<>();
96 for (SchemaTransformerRegistration tr : ts) {
97 final SchemaSourceTransformer<?, ?> t = tr.getInstance();
98 final Class<?> i = t.getInputRepresentation();
99 if (srcs.containsKey(i)) {
102 LOG.debug("Provider for {} in {} not found, skipping transfomer {}", id, i, t);
106 if (candidates.isEmpty()) {
107 return Futures.immediateFailedFuture(new SchemaSourceTransformationException(
108 String.format("No matching source/transformer pair for source %s representation %s found", id, representation)));
111 Collections.sort(candidates, TRANSFORMER_COST_COMPARATOR);
112 // return transform(candidates.iterator(), id);
117 * Obtain a SchemaSource is selected representation
119 protected <T extends SchemaSourceRepresentation> ListenableFuture<Optional<T>> getSchemaSource(final SourceIdentifier id, final Class<T> representation) {
120 final Multimap<Class<?>, AbstractSchemaSourceRegistration> srcs = sources.get(id);
122 LOG.debug("No providers registered for source {}", id);
123 return Futures.immediateFuture(Optional.<T>absent());
126 final Collection<AbstractSchemaSourceRegistration> candidates = srcs.get(representation);
127 return Futures.transform(AbstractSchemaRepository.<T>fetchSource(id, candidates.iterator()), new AsyncFunction<Optional<T>, Optional<T>>() {
129 public ListenableFuture<Optional<T>> apply(final Optional<T> input) throws Exception {
130 if (input.isPresent()) {
131 return Futures.immediateFuture(input);
134 return transformSchemaSource(id, representation);
140 public SchemaContextFactory createSchemaContextFactory(final SchemaSourceFilter filter) {
141 // TODO Auto-generated method stub
145 private void addSource(final SourceIdentifier id, final Class<?> rep, final AbstractSchemaSourceRegistration reg) {
146 Multimap<Class<?>, AbstractSchemaSourceRegistration> m = sources.get(id);
148 m = HashMultimap.create();
155 private void removeSource(final SourceIdentifier id, final Class<?> rep, final SchemaSourceRegistration reg) {
156 final Multimap<Class<?>, AbstractSchemaSourceRegistration> m = sources.get(id);
166 public <T extends SchemaSourceRepresentation> SchemaSourceRegistration registerSchemaSource(
167 final SourceIdentifier identifier, final SchemaSourceProvider<? super T> provider, final Class<T> representation) {
168 final AbstractSchemaSourceRegistration ret = new AbstractSchemaSourceRegistration(identifier, provider) {
170 protected void removeRegistration() {
171 removeSource(identifier, representation, this);
175 addSource(identifier, representation, ret);
180 public SchemaTransformerRegistration registerSchemaSourceTransformer(final SchemaSourceTransformer<?, ?> transformer) {
181 final SchemaTransformerRegistration ret = new AbstractSchemaTransformerRegistration(transformer) {
183 protected void removeRegistration() {
184 transformers.remove(transformer.getOutputRepresentation(), this);
188 transformers.put(transformer.getOutputRepresentation(), ret);