+/*
+ * 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.concepts;
import java.util.EventListener;
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.yangtools.concepts;\r
\r
/**\r
+/*
+ * 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.concepts;
/**
+/*
+ * 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.concepts;
public interface ClassBasedPropertyBuilder<P,T extends ClassBasedPropertyBuilder<P,T>> extends Builder<P> {
+/*
+ * 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.concepts;
public interface Codec<P,I> extends Serializer<P, I>, Deserializer<I, P> {
+/*
+ * 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.concepts;
import java.util.Collection;
+/*
+ * 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.concepts;
/**
+/*
+ * 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.concepts;
public interface Deserializer<P,I> {
+/*
+ * 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.concepts;
public interface InvertibleTransformator<P, I> extends Transformator<P, I>{
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.yangtools.concepts;\r
\r
import java.util.Set;\r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.yangtools.concepts;\r
import java.util.List;\r
import java.util.Set;\r
+/*
+ * 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.concepts;
public interface Serializer<P,I> {
+/*
+ * 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.concepts;
public interface Transformator<P,I> {
--- /dev/null
+/*
+ * 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.concepts.util;
+
+import static org.opendaylight.yangtools.concepts.util.ClassLoaderUtils.findParameterizedType;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.concurrent.Callable;
+import java.util.concurrent.locks.Lock;
+
+
+public final class ClassLoaderUtils {
+
+ private ClassLoaderUtils() {
+ throw new UnsupportedOperationException("Utility class");
+ }
+
+ public static <V> V withClassLoader(ClassLoader cls, Callable<V> function) throws Exception {
+ return withClassLoaderAndLock(cls, null, function);
+ }
+
+ public static <V> V withClassLoaderAndLock(ClassLoader cls, Lock lock, Callable<V> function) throws Exception {
+ if (cls == null) {
+ throw new IllegalArgumentException("Classloader should not be null");
+ }
+ if (function == null) {
+ throw new IllegalArgumentException("Function should not be null");
+ }
+
+ if (lock != null) {
+ lock.lock();
+ }
+ ClassLoader oldCls = Thread.currentThread().getContextClassLoader();
+ try {
+ Thread.currentThread().setContextClassLoader(cls);
+ return function.call();
+ } finally {
+ Thread.currentThread().setContextClassLoader(oldCls);
+ if (lock != null) {
+ lock.unlock();
+ }
+ }
+ }
+
+ public static ParameterizedType findParameterizedType(Class<?> subclass, Class<?> genericType) {
+ if(subclass == null || genericType == null) {
+ throw new IllegalArgumentException("Class was not specified.");
+ }
+ for (Type type : subclass.getGenericInterfaces()) {
+ if (type instanceof ParameterizedType && genericType.equals(((ParameterizedType) type).getRawType())) {
+ return (ParameterizedType) type;
+ }
+ }
+ return null;
+ }
+
+ public static <S,G,P> Class<P> findFirstGenericArgument(final Class<S> scannedClass, final Class<G> genericType) {
+ try {
+ return withClassLoader(scannedClass.getClassLoader(), ClassLoaderUtils.<S,G,P>findFirstGenericArgumentTask(scannedClass, genericType));
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ private static <S,G,P> Callable<Class<P>> findFirstGenericArgumentTask(final Class<S> scannedClass, final Class<G> genericType) {
+ return new Callable<Class<P>>() {
+ @Override
+ @SuppressWarnings("unchecked")
+ public Class<P> call() throws Exception {
+ final ParameterizedType augmentationGeneric = findParameterizedType(scannedClass,
+ genericType);
+ if (augmentationGeneric == null) {
+ return null;
+ }
+ return (Class<P>) augmentationGeneric.getActualTypeArguments()[0];
+ }
+ };
+ }
+
+}
\ No newline at end of file
+/*
+ * 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.concepts.util;
+import java.lang.reflect.Proxy;
import java.util.Collections;
import java.util.EventListener;
import java.util.Set;
public class ListenerRegistry<T extends EventListener> implements Iterable<ListenerRegistration<T>> {
- final ConcurrentHashMap<ListenerRegistration<T>,ListenerRegistration<T>> listeners;
+ private final ConcurrentHashMap<ListenerRegistration<? extends T>,ListenerRegistration<? extends T>> listeners;
final Set<ListenerRegistration<T>> unmodifiableView;
+ private T invoker;
+ @SuppressWarnings("unchecked")
public ListenerRegistry() {
listeners = new ConcurrentHashMap<>();
- unmodifiableView = Collections.unmodifiableSet(listeners.keySet());
+ // This conversion is known to be safe.
+ @SuppressWarnings("rawtypes")
+ final Set rawSet = Collections.unmodifiableSet(listeners.keySet());
+ unmodifiableView = rawSet;
}
public Iterable<ListenerRegistration<T>> getListeners() {
return unmodifiableView;
}
- public ListenerRegistration<T> register(T listener) {
+ public <F extends T> ListenerRegistration<F> register(F listener) {
if (listener == null) {
throw new IllegalArgumentException("Listener should not be null.");
}
- ListenerRegistrationImpl<T> ret = new ListenerRegistrationImpl<T>(listener);
+ ListenerRegistrationImpl<F> ret = new ListenerRegistrationImpl<F>(listener);
listeners.put(ret,ret);
return ret;
}
+/*
+ * 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);
}
+/*
+ * 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> {
--- /dev/null
+/*
+ * 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);
+ }
+}
+/*
+ * 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> {
import org.opendaylight.yangtools.concepts.Immutable;
import org.opendaylight.yangtools.concepts.Path;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
/**
}
public InstanceIdentifier(List<PathArgument> path, Class<T> type) {
- this.path = Collections.<PathArgument> unmodifiableList(new ArrayList<>(path));
+ this.path = ImmutableList.copyOf(path);
this.targetType = type;
}
--- /dev/null
+/*
+ * 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();
+ }
+ }
+
+}