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/epl-v10.html
8 package org.opendaylight.yangtools.yang.model.repo.api;
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static java.util.Objects.requireNonNull;
13 import com.google.common.annotations.Beta;
14 import com.google.common.base.MoreObjects;
15 import com.google.common.base.MoreObjects.ToStringHelper;
16 import com.google.common.io.ByteSource;
17 import com.google.common.io.Resources;
19 import java.io.InputStream;
21 import java.util.Map.Entry;
22 import javax.annotation.Nonnull;
23 import org.opendaylight.yangtools.yang.common.Revision;
24 import org.opendaylight.yangtools.yang.common.YangConstants;
25 import org.opendaylight.yangtools.yang.common.YangNames;
28 * YANG text schema source representation. Exposes an RFC6020 or RFC7950 text representation
29 * as an {@link InputStream}.
32 public abstract class YangTextSchemaSource extends ByteSource implements YangSchemaSourceRepresentation {
33 private final SourceIdentifier identifier;
35 protected YangTextSchemaSource(final SourceIdentifier identifier) {
36 this.identifier = requireNonNull(identifier);
39 public static SourceIdentifier identifierFromFilename(final String name) {
40 checkArgument(name.endsWith(YangConstants.RFC6020_YANG_FILE_EXTENSION),
41 "Filename %s does not have a .yang extension", name);
43 final String baseName = name.substring(0, name.length() - YangConstants.RFC6020_YANG_FILE_EXTENSION.length());
44 final Entry<String, String> parsed = YangNames.parseFilename(baseName);
45 return RevisionSourceIdentifier.create(parsed.getKey(), parsed.getValue() == null ? null
46 : Revision.valueOf(parsed.getValue()));
50 * Create a new YangTextSchemaSource with a specific source identifier and backed
51 * by ByteSource, which provides the actual InputStreams.
53 * @param identifier SourceIdentifier of the resulting schema source
54 * @param delegate Backing ByteSource instance
55 * @return A new YangTextSchemaSource
57 public static YangTextSchemaSource delegateForByteSource(final SourceIdentifier identifier,
58 final ByteSource delegate) {
59 return new DelegatedYangTextSchemaSource(identifier, delegate);
63 * Create a new YangTextSchemaSource with {@link SourceIdentifier} derived from a supplied filename and backed
64 * by ByteSource, which provides the actual InputStreams.
66 * @param fileName File name
67 * @param delegate Backing ByteSource instance
68 * @return A new YangTextSchemaSource
69 * @throws IllegalArgumentException if the file name has invalid format
71 public static YangTextSchemaSource delegateForByteSource(final String fileName, final ByteSource delegate) {
72 return new DelegatedYangTextSchemaSource(identifierFromFilename(fileName), delegate);
76 * Create a new YangTextSchemaSource backed by a {@link File} with {@link SourceIdentifier} derived from the file
79 * @param file Backing File
80 * @return A new YangTextSchemaSource
81 * @throws IllegalArgumentException if the file name has invalid format or if the supplied File is not a file
82 * @throws NullPointerException if file is null
84 public static YangTextSchemaSource forFile(final File file) {
85 checkArgument(file.isFile(), "Supplied file %s is not a file");
86 return new YangTextFileSchemaSource(identifierFromFilename(file.getName()), file);
90 * Create a new {@link YangTextSchemaSource} backed by a resource available in the ClassLoader where this
93 * @param resourceName Resource name
94 * @return A new instance.
95 * @throws IllegalArgumentException if the resource does not exist or if the name has invalid format
97 public static ResourceYangTextSchemaSource forResource(final String resourceName) {
98 return forResource(YangTextSchemaSource.class, resourceName);
102 * Create a new {@link YangTextSchemaSource} backed by a resource by a resource available on the ClassLoader
103 * which loaded the specified class.
105 * @param clazz Class reference
106 * @param resourceName Resource name
107 * @return A new instance.
108 * @throws IllegalArgumentException if the resource does not exist or if the name has invalid format
110 public static ResourceYangTextSchemaSource forResource(final Class<?> clazz, final String resourceName) {
111 final String fileName = resourceName.substring(resourceName.lastIndexOf('/') + 1);
112 final SourceIdentifier identifier = identifierFromFilename(fileName);
113 final URL url = Resources.getResource(clazz, resourceName);
114 return new ResourceYangTextSchemaSource(identifier, url);
118 public final SourceIdentifier getIdentifier() {
124 public Class<? extends YangTextSchemaSource> getType() {
125 return YangTextSchemaSource.class;
129 public final String toString() {
130 return addToStringAttributes(MoreObjects.toStringHelper(this).add("identifier", identifier)).toString();
134 * Add subclass-specific attributes to the output {@link #toString()} output. Since
135 * subclasses are prevented from overriding {@link #toString()} for consistency
136 * reasons, they can add their specific attributes to the resulting string by attaching
137 * attributes to the supplied {@link ToStringHelper}.
139 * @param toStringHelper ToStringHelper onto the attributes can be added
140 * @return ToStringHelper supplied as input argument.
142 protected abstract ToStringHelper addToStringAttributes(ToStringHelper toStringHelper);