Added headers to the concepts bundles
authorTony Tkacik <ttkacik@cisco.com>
Thu, 12 Dec 2013 00:37:36 +0000 (01:37 +0100)
committerTony Tkacik <ttkacik@cisco.com>
Thu, 12 Dec 2013 00:37:36 +0000 (01:37 +0100)
  Extracted some of utility code and constants to the concepts and
  yang-binding where it respectivelly belong.

Signed-off-by: Tony Tkacik <ttkacik@cisco.com>
yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/BindingCodec.java
yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/BindingDeserializer.java
yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/BindingMapping.java [new file with mode: 0644]
yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/BindingSerializer.java
yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/InstanceIdentifier.java
yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/util/BindingReflections.java [new file with mode: 0644]

index f8bb91b736819ea5a0993d74b473734f70a43d84..00c14594eef1b0988679d75a9fc7b40a7533fa80 100644 (file)
@@ -1,10 +1,22 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.yangtools.yang.binding;
 
-public interface BindingCodec<P,I>  extends BindingSerializer<P, I>, BindingDeserializer<I, P> {
+import org.opendaylight.yangtools.concepts.Codec;
+
+public interface BindingCodec<P, I> extends //
+        BindingSerializer<P, I>, //
+        BindingDeserializer<I, P>, //
+        Codec<P, I> {
 
     @Override
     public P serialize(I input);
-    
+
     @Override
     public I deserialize(P input);
 }
index cc97a956221e5e6afc9bd98d0d997667be2ca211..dea3d992db99f03e07b70df229654dcd848554e9 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.yangtools.yang.binding;
 
 public interface BindingDeserializer<P,I> {
diff --git a/yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/BindingMapping.java b/yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/BindingMapping.java
new file mode 100644 (file)
index 0000000..00a36d9
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.binding;
+
+import java.util.Set;
+
+import org.opendaylight.yangtools.yang.common.QName;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableSet;
+import static com.google.common.base.Preconditions.*;
+
+public final class BindingMapping {
+
+    public static final String VERSION = "0.6";
+
+    public static final Set<String> JAVA_RESERVED_WORDS = ImmutableSet.of("abstract", "assert", "boolean", "break",
+            "byte", "case", "catch", "char", "class", "const", "continue", "default", "double", "do", "else", "enum",
+            "extends", "false", "final", "finally", "float", "for", "goto", "if", "implements", "import", "instanceof",
+            "int", "interface", "long", "native", "new", "null", "package", "private", "protected", "public", "return",
+            "short", "static", "strictfp", "super", "switch", "synchronized", "this", "throw", "throws", "transient",
+            "true", "try", "void", "volatile", "while");
+
+    public static final String DATA_ROOT_SUFFIX = "Data";
+    public static final String RPC_SERVICE_SUFFIX = "Service";
+    public static final String NOTIFICATION_LISTENER_SUFFIX = "Listener";
+    public static final String QNAME_STATIC_FIELD_NAME = "QNAME";
+
+    private static final Splitter SPACE_SPLITTER = Splitter.on(" ").omitEmptyStrings().trimResults();
+
+    public static final String getMethodName(QName name) {
+        checkArgument(name != null, "Name should not be null.");
+        return toFirstLower(toCamelCase(name.getLocalName()));
+    }
+
+    public static final String getClassName(String localName) {
+        return toFirstUpper(toCamelCase(localName));
+    }
+
+    public static final String getClassName(QName name) {
+        checkArgument(name != null, "Name should not be null.");
+        return toFirstUpper(toCamelCase(name.getLocalName()));
+    }
+
+    private static final String toCamelCase(String rawString) {
+        checkArgument(rawString != null, "String should not be null");
+        Iterable<String> components = SPACE_SPLITTER.split(rawString.replace('-', ' ').replace('_', ' '));
+        StringBuilder builder = new StringBuilder();
+        for (String comp : components) {
+            builder.append(toFirstUpper(comp));
+        }
+        return builder.toString();
+    }
+
+    /**
+     * Returns the {@link String} {@code s} with an
+     * {@link Character#isUpperCase(char) upper case} first character. This
+     * function is null-safe.
+     * 
+     * @param s
+     *            the string that should get an upper case first character. May
+     *            be <code>null</code>.
+     * @return the {@link String} {@code s} with an upper case first character
+     *         or <code>null</code> if the input {@link String} {@code s} was
+     *         <code>null</code>.
+     */
+    private static String toFirstUpper(String s) {
+        if (s == null || s.length() == 0)
+            return s;
+        if (Character.isUpperCase(s.charAt(0)))
+            return s;
+        if (s.length() == 1)
+            return s.toUpperCase();
+        return s.substring(0, 1).toUpperCase() + s.substring(1);
+    }
+
+    /**
+     * Returns the {@link String} {@code s} with an
+     * {@link Character#isLowerCase(char) lower case} first character. This
+     * function is null-safe.
+     * 
+     * @param s
+     *            the string that should get an lower case first character. May
+     *            be <code>null</code>.
+     * @return the {@link String} {@code s} with an lower case first character
+     *         or <code>null</code> if the input {@link String} {@code s} was
+     *         <code>null</code>.
+     */
+    private static String toFirstLower(String s) {
+        if (s == null || s.length() == 0)
+            return s;
+        if (Character.isLowerCase(s.charAt(0)))
+            return s;
+        if (s.length() == 1)
+            return s.toLowerCase();
+        return s.substring(0, 1).toLowerCase() + s.substring(1);
+    }
+}
index a0e355b693447b401552eb3f00cbdfea087c930e..fb85eae9f783f3f9ed19cb2c2120946792b4f5bb 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.yangtools.yang.binding;
 
 public interface BindingSerializer<P,I> {
index 16a06e139f70c89c4daa361b9e0a5c47af3cd5b8..09f0dc13c35cfcbe40f5729f67d06ffc71d352ea 100644 (file)
@@ -15,6 +15,7 @@ import org.opendaylight.yangtools.concepts.Builder;
 import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.concepts.Path;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 
 /**
@@ -34,7 +35,7 @@ public final class InstanceIdentifier<T extends DataObject> implements Path<Inst
     }
 
     public InstanceIdentifier(List<PathArgument> path, Class<T> type) {
-        this.path = Collections.<PathArgument> unmodifiableList(new ArrayList<>(path));
+        this.path = ImmutableList.copyOf(path);
         this.targetType = type;
     }
 
diff --git a/yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/util/BindingReflections.java b/yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/util/BindingReflections.java
new file mode 100644 (file)
index 0000000..3e1e7b8
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.binding.util;
+
+import java.lang.reflect.Field;
+import java.util.concurrent.TimeUnit;
+
+import org.opendaylight.yangtools.concepts.util.ClassLoaderUtils;
+import org.opendaylight.yangtools.yang.binding.Augmentable;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
+import org.opendaylight.yangtools.yang.binding.BindingMapping;
+import org.opendaylight.yangtools.yang.binding.ChildOf;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.common.QName;
+
+import com.google.common.base.Optional;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+
+public class BindingReflections {
+
+    private static final long EXPIRATION_TIME = 60;
+
+    private static final LoadingCache<Class<?>, Optional<QName>> classToQName = CacheBuilder.newBuilder() //
+            .weakKeys() //
+            .expireAfterAccess(EXPIRATION_TIME, TimeUnit.SECONDS) //
+            .build(new ClassToQNameLoader());
+
+    /**
+     * 
+     * @param augmentation
+     *            {@link Augmentation} subclass for which we want to determine
+     *            augmentation target.
+     * @return Augmentation target - class which augmentation provides
+     *         additional extensions.
+     */
+    public static Class<? extends Augmentable<?>> findAugmentationTarget(
+            final Class<? extends Augmentation<?>> augmentation) {
+        return ClassLoaderUtils.findFirstGenericArgument(augmentation, Augmentation.class);
+    }
+
+    /**
+     * 
+     * @param augmentation
+     *            {@link Augmentation} subclass for which we want to determine
+     *            augmentation target.
+     * @return Augmentation target - class which augmentation provides
+     *         additional extensions.
+     */
+    public static Class<?> findHierarchicalParent(final Class<? extends ChildOf<?>> childClass) {
+        return ClassLoaderUtils.findFirstGenericArgument(childClass, ChildOf.class);
+    }
+
+    /**
+     * 
+     * @param augmentation
+     *            {@link Augmentation} subclass for which we want to determine
+     *            augmentation target.
+     * @return Augmentation target - class which augmentation provides
+     *         additional extensions.
+     */
+    public static Class<?> findHierarchicalParent(DataObject childClass) {
+        if (childClass instanceof ChildOf) {
+            return ClassLoaderUtils.findFirstGenericArgument(childClass.getImplementedInterface(), ChildOf.class);
+        }
+        return null;
+    }
+
+    public static final QName findQName(Class<? extends DataContainer> dataType) {
+        return classToQName.getUnchecked(dataType).orNull();
+    }
+
+    private static class ClassToQNameLoader extends CacheLoader<Class<?>, Optional<QName>> {
+
+        @Override
+        public Optional<QName> load(Class<?> key) throws Exception {
+            try {
+                Field field = key.getField(BindingMapping.QNAME_STATIC_FIELD_NAME);
+                Object obj = field.get(null);
+                if (obj instanceof QName) {
+                    return Optional.of((QName) obj);
+                }
+            } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
+                // NOOP
+            }
+            return Optional.absent();
+        }
+    }
+
+}