org.jclouds.rest.config.ReadAnnotationsAndProperties.java Source code

Java tutorial

Introduction

Here is the source code for org.jclouds.rest.config.ReadAnnotationsAndProperties.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jclouds.rest.config;

import static com.google.common.base.Optional.fromNullable;
import static com.google.common.collect.Maps.transformValues;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.jclouds.Constants.PROPERTY_TIMEOUTS_PREFIX;
import static org.jclouds.util.Maps2.transformKeys;
import static org.jclouds.util.Predicates2.startsWith;

import java.util.Map;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;

import org.jclouds.reflect.Invocation;
import org.jclouds.rest.annotations.Fallback;

import com.google.common.annotations.Beta;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.reflect.Invokable;
import com.google.inject.Injector;

@Beta
@Singleton
public class ReadAnnotationsAndProperties implements InvocationConfig {
    private final Injector injector;
    private final org.jclouds.Fallback<Object> defaultFallback;
    private final Map<String, Long> timeouts;

    @Inject
    ReadAnnotationsAndProperties(Injector injector,
            Function<Predicate<String>, Map<String, String>> filterStringsBoundByName,
            org.jclouds.Fallback<Object> defaultFallback) {
        this.injector = injector;
        this.defaultFallback = defaultFallback;
        this.timeouts = timeouts(filterStringsBoundByName);
    }

    @Override
    public Optional<Long> getTimeoutNanos(Invocation in) {
        String commandName = getCommandName(in);
        Optional<Long> defaultMillis = fromNullable(timeouts.get("default"));
        Optional<Long> timeoutMillis = fromNullable(timeouts.get(commandName));
        Invokable<?, ?> invoked = in.getInvokable();
        if (invoked.isAnnotationPresent(Named.class)) {
            timeoutMillis = timeoutMillis.or(defaultMillis);
        } else {
            // TODO: remove old logic once Named annotations are on all methods
            String className = invoked.getOwnerType().getRawType().getSimpleName().replace("AsyncClient", "Client")
                    .replace("AsyncApi", "Api");
            timeoutMillis = timeoutMillis.or(fromNullable(timeouts.get(className))).or(defaultMillis);
        }
        if (timeoutMillis.isPresent())
            return Optional.of(MILLISECONDS.toNanos(timeoutMillis.get()));
        return Optional.absent();
    }

    @Override
    public String getCommandName(Invocation invocation) {
        Invokable<?, ?> invoked = invocation.getInvokable();
        if (invoked.isAnnotationPresent(Named.class)) {
            return invoked.getAnnotation(Named.class).value();
        } else {
            // TODO: remove old logic once Named annotations are on all methods
            String className = invoked.getOwnerType().getRawType().getSimpleName().replace("AsyncClient", "Client")
                    .replace("AsyncApi", "Api");
            return className + "." + invoked.getName();
        }
    }

    @Override
    public org.jclouds.Fallback<?> getFallback(Invocation invocation) {
        Fallback fallback = invocation.getInvokable().getAnnotation(Fallback.class);
        if (fallback != null) {
            return injector.getInstance(fallback.value());
        }
        return defaultFallback;
    }

    /**
     * override timeout by values configured in properties(in ms)
     */
    static Map<String, Long> timeouts(Function<Predicate<String>, Map<String, String>> filterStringsBoundByName) {
        Map<String, String> stringBoundWithTimeoutPrefix = filterStringsBoundByName
                .apply(startsWith(PROPERTY_TIMEOUTS_PREFIX));
        Map<String, Long> longsByName = transformValues(stringBoundWithTimeoutPrefix, new Function<String, Long>() {
            public Long apply(String input) {
                return Long.valueOf(String.valueOf(input));
            }
        });
        return transformKeys(longsByName, new Function<String, String>() {
            public String apply(String input) {
                return input.replaceFirst(PROPERTY_TIMEOUTS_PREFIX, "");
            }
        });
    }
}