ede74c6a93fb247b574d7f752ace83170ca6d3e3
[yangtools.git] / yang / yang-model-util / src / main / java / org / opendaylight / yangtools / yang / model / util / repo / AbstractCachingSchemaSourceProvider.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.yang.model.util.repo;
9
10 import com.google.common.annotations.Beta;
11 import com.google.common.base.Optional;
12 import com.google.common.base.Preconditions;
13 import org.opendaylight.yangtools.concepts.Delegator;
14
15
16 /**
17  *
18  * Abstract caching schema provider with support of multiple context
19  * per backing {@link SchemaSourceProvider}.
20  *
21  * @param <I> Input Schema Source Representation
22  * @param <O> Output Schema Source Representation
23  *
24  * @deprecated Replaced with {@link org.opendaylight.yangtools.yang.model.repo.util.AbstractSchemaSourceCache}
25  */
26 @Deprecated
27 public abstract class AbstractCachingSchemaSourceProvider<I, O> implements AdvancedSchemaSourceProvider<O>,
28         Delegator<AdvancedSchemaSourceProvider<I>> {
29
30     private final AdvancedSchemaSourceProvider<I> defaultDelegate;
31
32     /**
33      * Construct caching schema source provider with supplied delegate.
34      *
35      * Default delegate is is used to retrieve schema source when cache does not
36      * contain requested sources.
37      *
38      * @param delegate SchemaSourceProvided used to look up and retrieve schema source
39      * when cache does not contain requested sources.
40      */
41     protected AbstractCachingSchemaSourceProvider(final AdvancedSchemaSourceProvider<I> delegate) {
42         this.defaultDelegate = delegate;
43     }
44
45     @Override
46     public Optional<O> getSchemaSource(final String moduleName, final Optional<String> revision) {
47         Preconditions.checkNotNull(moduleName, "Module name should not be null.");
48         Preconditions.checkNotNull(revision, "Revision should not be null");
49         return getSchemaSource(SourceIdentifier.create(moduleName, revision));
50     }
51
52     @Override
53     public Optional<O> getSchemaSource(final SourceIdentifier sourceIdentifier) {
54         return getSchemaSourceImpl(sourceIdentifier, defaultDelegate);
55     }
56
57     /**
58      * Actual implementation of schema source retrieval.
59      *
60      * <ul>
61      * <li>look up cached schema source via {@link #getCachedSchemaSource(SourceIdentifier)}
62      * <li>If source was found in cache, returns source to client code.
63      * <li>If source was not found in cache, Look up schema source in supplied <code>delegate</code>
64      * <li>Updates cache with schema from delegate by {@link #cacheSchemaSource(SourceIdentifier, Optional)}
65      * <li>Result is returned to client code.
66      * </ul>
67      *
68      * @param identifier Source identifier
69      * @param delegate Delegate to lookup if there is a miss.
70      * @return Optional of schema source, present if source was found. Absent otherwise.
71      */
72     protected final Optional<O> getSchemaSourceImpl(final SourceIdentifier identifier,
73             final AdvancedSchemaSourceProvider<I> delegate) {
74         Preconditions.checkNotNull(identifier, "Source identifier name should not be null.");
75
76         Optional<O> cached = getCachedSchemaSource(identifier);
77         if (cached.isPresent()) {
78             return cached;
79         }
80         Optional<I> live = delegate.getSchemaSource(identifier);
81         return cacheSchemaSource(identifier, live);
82     }
83
84     /**
85      * Caches supplied result and returns cached result which should be returned to client.
86      *
87      * <p>
88      * Implementations of cache are required to cache schema source if possible.
89      * They are not required to cache {@link Optional#absent()}.
90      *
91      * Implementations are required to transform source representation if <code>O</code> and <code>I</code>
92      * are different.
93      *
94      * This method SHOULD NOT fail and should recover from Runtime exceptions
95      * by not caching source and only transforming it.
96      *
97      * @param identifier Source Identifier for which schema SHOULD be cached
98      * @param input Optional of schema source, representing one returned from delegate.
99      * @return Optional of schema source, representing result returned from this cache.
100      */
101     protected abstract Optional<O> cacheSchemaSource(SourceIdentifier identifier, Optional<I> input);
102
103     /**
104      * Returns cached schema source of {@link Optional#absent()} if source is not present in cache.
105      *
106      * <p>
107      * Implementations of cache MUST return cached schema source, if it is present in cache,
108      * otherwise source will be requested from deleate and then cache will be updated
109      * via {@link #cacheSchemaSource(SourceIdentifier, Optional)}.
110      *
111      * @param identifier Source Identifier for which schema should be retrieved.
112      * @return Cached schema source.
113      */
114     protected abstract Optional<O> getCachedSchemaSource(SourceIdentifier identifier);
115
116     @Override
117     public AdvancedSchemaSourceProvider<I> getDelegate() {
118         return defaultDelegate;
119     }
120
121     /**
122      * Creates an lightweight instance of source provider, which uses this cache for caching
123      * and supplied additional delegate for lookup of not cached sources.
124      * <p>
125      *
126      * @param delegate Backing {@link SchemaSourceProvider} which should be used for lookup
127      *   for sources not present in schema.
128      * @return new instance of {@link SchemaSourceProvider} which first lookup in cache
129      *   and then in delegate.
130      *
131      */
132     @Beta
133     public SchemaSourceProvider<O> createInstanceFor(final SchemaSourceProvider<I> delegate) {
134         return new SchemaSourceProviderInstance(SchemaSourceProviders.toAdvancedSchemaSourceProvider(delegate));
135
136     }
137
138     /**
139      *
140      * Lightweight instance of source provider, which is associated with parent
141      * {@link AbstractCachingSchemaSourceProvider}, but uses
142      * different delegate for retrieving not cached sources.
143      *
144      */
145     @Beta
146     private class SchemaSourceProviderInstance implements AdvancedSchemaSourceProvider<O>, Delegator<AdvancedSchemaSourceProvider<I>> {
147
148         private final AdvancedSchemaSourceProvider<I> delegate;
149
150         protected SchemaSourceProviderInstance(final AdvancedSchemaSourceProvider<I> delegate) {
151             super();
152             this.delegate = Preconditions.checkNotNull(delegate, "Delegate should not be null");
153         }
154
155         @Override
156         public Optional<O> getSchemaSource(final String moduleName, final Optional<String> revision) {
157             return getSchemaSource(SourceIdentifier.create(moduleName, revision));
158         }
159
160         @Override
161         public AdvancedSchemaSourceProvider<I> getDelegate() {
162             return delegate;
163         }
164
165         @Override
166         public Optional<O> getSchemaSource(final SourceIdentifier sourceIdentifier) {
167             return getSchemaSourceImpl(sourceIdentifier, getDelegate());
168         }
169     }
170 }