<commit_before>/*
 * Copyright 2013-2016 the original author or authors.
 *
 * Licensed 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.glowroot.ui;

import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Nullable;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.immutables.value.Value;

import org.glowroot.common.repo.AgentRepository;
import org.glowroot.common.repo.AgentRepository.AgentRollup;
import org.glowroot.common.repo.ConfigRepository;
import org.glowroot.common.repo.ConfigRepository.RollupConfig;
import org.glowroot.common.repo.TransactionTypeRepository;
import org.glowroot.common.util.ObjectMappers;
import org.glowroot.common.util.Versions;
import org.glowroot.ui.HttpSessionManager.Authentication;
import org.glowroot.wire.api.model.AgentConfigOuterClass.AgentConfig.UiConfig;

import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.concurrent.TimeUnit.HOURS;

class LayoutService {

    private static final String AGENT_ID = "";

    private static final ObjectMapper mapper = ObjectMappers.create();

    private final boolean fat;
    private final boolean offlineViewer;
    private final String version;
    private final ConfigRepository configRepository;
    private final AgentRepository agentRepository;
    private final TransactionTypeRepository transactionTypeRepository;

    LayoutService(boolean fat, boolean offlineViewer, String version,
            ConfigRepository configRepository, AgentRepository agentRepository,
            TransactionTypeRepository transactionTypeRepository) {
        this.fat = fat;
        this.offlineViewer = offlineViewer;
        this.version = version;
        this.configRepository = configRepository;
        this.agentRepository = agentRepository;
        this.transactionTypeRepository = transactionTypeRepository;
    }

    String getLayout(Authentication authentication) throws Exception {
        Layout layout = buildLayout(authentication);
        return mapper.writeValueAsString(layout);
    }

    String getLayoutVersion(Authentication authentication) throws Exception {
        Layout layout = buildLayout(authentication);
        return layout.version();
    }

    private Layout buildLayout(Authentication authentication) throws Exception {
        // linked hash map to preserve ordering
        Map<String, AgentRollupLayout> agentRollups = Maps.newLinkedHashMap();
        Map<String, List<String>> transactionTypesMap =
                transactionTypeRepository.readTransactionTypes();
        boolean hasSomeAccess = false;
        boolean showNavbarTransaction = false;
        boolean showNavbarError = false;
        boolean showNavbarJvm = false;
        boolean showNavbarConfig = false;
        if (fat) {
            Permissions permissions = getPermissions(authentication, AGENT_ID);
            hasSomeAccess =
                    permissions.hasSomeAccess() || authentication.isAdminPermitted("admin:view");
            showNavbarTransaction = permissions.transaction().hasSomeAccess();
            showNavbarError = permissions.error().hasSomeAccess();
            showNavbarJvm = permissions.jvm().hasSomeAccess();
            showNavbarConfig = permissions.config().view();
            if (hasSomeAccess) {
                // a couple of special cases for fat agent
                UiConfig uiConfig = checkNotNull(configRepository.getUiConfig(AGENT_ID));
                String defaultDisplayedTransactionType =
                        uiConfig.getDefaultDisplayedTransactionType();
                Set<String> transactionTypes = Sets.newHashSet();
                List<String> storedTransactionTypes = transactionTypesMap.get(AGENT_ID);
                if (storedTransactionTypes != null) {
                    transactionTypes.addAll(storedTransactionTypes);
                }
                transactionTypes.add(defaultDisplayedTransactionType);

                agentRollups.put(AGENT_ID, ImmutableAgentRollupLayout.builder()
                        .leaf(true)
                        .permissions(permissions)
                        .addAllTransactionTypes(transactionTypes)
                        .defaultDisplayedTransactionType(defaultDisplayedTransactionType)
                        .defaultDisplayedPercentiles(uiConfig.getDefaultDisplayedPercentileList())
                        .build());
                showNavbarConfig = checkNotNull(permissions.config()).view();
            }
        } else if (!fat) {
            for (AgentRollup agentRollup : agentRepository.readAgentRollups()) {
                Permissions permissions = getPermissions(authentication, agentRollup.name());
                if (!permissions.hasSomeAccess()) {
                    continue;
                }
                hasSomeAccess = true;
                showNavbarTransaction =
                        showNavbarTransaction || permissions.transaction().hasSomeAccess();
                showNavbarError = showNavbarError || permissions.error().hasSomeAccess();
                showNavbarJvm = showNavbarJvm || permissions.jvm().hasSomeAccess();
                showNavbarConfig = showNavbarConfig || permissions.config().view();
                UiConfig uiConfig = configRepository.getUiConfig(agentRollup.name());
                String defaultDisplayedTransactionType;
                List<Double> defaultDisplayedPercentiles;
                if (uiConfig == null) {
                    // TODO these defaults should be shared with UiConfig defaults
                    defaultDisplayedTransactionType = "Web";
                    defaultDisplayedPercentiles = ImmutableList.of(50.0, 95.0, 99.0);
                } else {
                    defaultDisplayedTransactionType = uiConfig.getDefaultDisplayedTransactionType();
                    defaultDisplayedPercentiles = uiConfig.getDefaultDisplayedPercentileList();
                }
                Set<String> transactionTypes = Sets.newHashSet();
                boolean leaf = agentRollup.leaf();
                ImmutableAgentRollupLayout.Builder builder = ImmutableAgentRollupLayout.builder()
                        .leaf(leaf);
                if (leaf) {
                    builder.permissions(permissions);
                }
                List<String> storedTransactionTypes = transactionTypesMap.get(agentRollup.name());
                if (storedTransactionTypes != null) {
                    transactionTypes.addAll(storedTransactionTypes);
                }
                transactionTypes.add(defaultDisplayedTransactionType);
                builder.addAllTransactionTypes(transactionTypes);
                builder.defaultDisplayedTransactionType(defaultDisplayedTransactionType);
                builder.defaultDisplayedPercentiles(defaultDisplayedPercentiles);
                agentRollups.put(agentRollup.name(), builder.build());
            }
            hasSomeAccess = hasSomeAccess || authentication.isAdminPermitted("admin:view");

        }
        if (hasSomeAccess) {
            List<Long> rollupExpirationMillis = Lists.newArrayList();
            for (long hours : configRepository.getStorageConfig().rollupExpirationHours()) {
                rollupExpirationMillis.add(HOURS.toMillis(hours));
            }
            return ImmutableLayout.builder()
                    .fat(fat)
                    .offlineViewer(offlineViewer)
                    .footerMessage("Glowroot version " + version)
                    .loginEnabled(offlineViewer ? false
                            : configRepository.namedUsersExist()
                                    || !configRepository.getLdapConfig().host().isEmpty())
                    .addAllRollupConfigs(configRepository.getRollupConfigs())
                    .addAllRollupExpirationMillis(rollupExpirationMillis)<commit_msg>Fix navbar when no agents have reported yet<commit_after>/*
 * Copyright 2013-2016 the original author or authors.
 *
 * Licensed 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.glowroot.ui;

import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Nullable;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.immutables.value.Value;

import org.glowroot.common.repo.AgentRepository;
import org.glowroot.common.repo.AgentRepository.AgentRollup;
import org.glowroot.common.repo.ConfigRepository;
import org.glowroot.common.repo.ConfigRepository.RollupConfig;
import org.glowroot.common.repo.TransactionTypeRepository;
import org.glowroot.common.util.ObjectMappers;
import org.glowroot.common.util.Versions;
import org.glowroot.ui.HttpSessionManager.Authentication;
import org.glowroot.wire.api.model.AgentConfigOuterClass.AgentConfig.UiConfig;

import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.concurrent.TimeUnit.HOURS;

class LayoutService {

    private static final String AGENT_ID = "";

    private static final ObjectMapper mapper = ObjectMappers.create();

    private final boolean fat;
    private final boolean offlineViewer;
    private final String version;
    private final ConfigRepository configRepository;
    private final AgentRepository agentRepository;
    private final TransactionTypeRepository transactionTypeRepository;

    LayoutService(boolean fat, boolean offlineViewer, String version,
            ConfigRepository configRepository, AgentRepository agentRepository,
            TransactionTypeRepository transactionTypeRepository) {
        this.fat = fat;
        this.offlineViewer = offlineViewer;
        this.version = version;
        this.configRepository = configRepository;
        this.agentRepository = agentRepository;
        this.transactionTypeRepository = transactionTypeRepository;
    }

    String getLayout(Authentication authentication) throws Exception {
        Layout layout = buildLayout(authentication);
        return mapper.writeValueAsString(layout);
    }

    String getLayoutVersion(Authentication authentication) throws Exception {
        Layout layout = buildLayout(authentication);
        return layout.version();
    }

    private Layout buildLayout(Authentication authentication) throws Exception {
        // linked hash map to preserve ordering
        Map<String, AgentRollupLayout> agentRollups = Maps.newLinkedHashMap();
        Map<String, List<String>> transactionTypesMap =
                transactionTypeRepository.readTransactionTypes();
        boolean hasSomeAccess = false;
        boolean showNavbarTransaction = false;
        boolean showNavbarError = false;
        boolean showNavbarJvm = false;
        boolean showNavbarConfig = false;
        if (fat) {
            Permissions permissions = getPermissions(authentication, AGENT_ID);
            hasSomeAccess =
                    permissions.hasSomeAccess() || authentication.isAdminPermitted("admin:view");
            showNavbarTransaction = permissions.transaction().hasSomeAccess();
            showNavbarError = permissions.error().hasSomeAccess();
            showNavbarJvm = permissions.jvm().hasSomeAccess();
            showNavbarConfig = permissions.config().view();
            if (hasSomeAccess) {
                // a couple of special cases for fat agent
                UiConfig uiConfig = checkNotNull(configRepository.getUiConfig(AGENT_ID));
                String defaultDisplayedTransactionType =
                        uiConfig.getDefaultDisplayedTransactionType();
                Set<String> transactionTypes = Sets.newHashSet();
                List<String> storedTransactionTypes = transactionTypesMap.get(AGENT_ID);
                if (storedTransactionTypes != null) {
                    transactionTypes.addAll(storedTransactionTypes);
                }
                transactionTypes.add(defaultDisplayedTransactionType);

                agentRollups.put(AGENT_ID, ImmutableAgentRollupLayout.builder()
                        .leaf(true)
                        .permissions(permissions)
                        .addAllTransactionTypes(transactionTypes)
                        .defaultDisplayedTransactionType(defaultDisplayedTransactionType)
                        .defaultDisplayedPercentiles(uiConfig.getDefaultDisplayedPercentileList())
                        .build());
                showNavbarConfig = checkNotNull(permissions.config()).view();
            }
        } else if (!fat) {
            // "*" is to check permissions for "all agents"
            Permissions permissions = getPermissions(authentication, "*");
            hasSomeAccess =
                    permissions.hasSomeAccess() || authentication.isAdminPermitted("admin:view");
            showNavbarTransaction = permissions.transaction().hasSomeAccess();
            showNavbarError = permissions.error().hasSomeAccess();
            showNavbarJvm = permissions.jvm().hasSomeAccess();
            showNavbarConfig = permissions.config().view();
            for (AgentRollup agentRollup : agentRepository.readAgentRollups()) {
                permissions = getPermissions(authentication, agentRollup.name());
                if (!permissions.hasSomeAccess()) {
                    continue;
                }
                hasSomeAccess = true;
                showNavbarTransaction =
                        showNavbarTransaction || permissions.transaction().hasSomeAccess();
                showNavbarError = showNavbarError || permissions.error().hasSomeAccess();
                showNavbarJvm = showNavbarJvm || permissions.jvm().hasSomeAccess();
                showNavbarConfig = showNavbarConfig || permissions.config().view();
                UiConfig uiConfig = configRepository.getUiConfig(agentRollup.name());
                String defaultDisplayedTransactionType;
                List<Double> defaultDisplayedPercentiles;
                if (uiConfig == null) {
                    // TODO these defaults should be shared with UiConfig defaults
                    defaultDisplayedTransactionType = "Web";
                    defaultDisplayedPercentiles = ImmutableList.of(50.0, 95.0, 99.0);
                } else {
                    defaultDisplayedTransactionType = uiConfig.getDefaultDisplayedTransactionType();
                    defaultDisplayedPercentiles = uiConfig.getDefaultDisplayedPercentileList();
                }
                Set<String> transactionTypes = Sets.newHashSet();
                boolean leaf = agentRollup.leaf();
                ImmutableAgentRollupLayout.Builder builder = ImmutableAgentRollupLayout.builder()
                        .leaf(leaf);
                if (leaf) {
                    builder.permissions(permissions);
                }
                List<String> storedTransactionTypes = transactionTypesMap.get(agentRollup.name());
                if (storedTransactionTypes != null) {
                    transactionTypes.addAll(storedTransactionTypes);
                }
                transactionTypes.add(defaultDisplayedTransactionType);
                builder.addAllTransactionTypes(transactionTypes);
                builder.defaultDisplayedTransactionType(defaultDisplayedTransactionType);
                builder.defaultDisplayedPercentiles(defaultDisplayedPercentiles);
                agentRollups.put(agentRollup.name(), builder.build());
            }
        }
        if (hasSomeAccess) {
            List<Long> rollupExpirationMillis = Lists.newArrayList();
            for (long hours : configRepository.getStorageConfig().rollupExpirationHours()) {
                rollupExpirationMillis.add(HOURS.toMillis(hours));
            }
            return ImmutableLayout.builder()
                    .fat(fat)
                    .offlineViewer(offlineViewer)
                    .footerMessage("Glowroot version " + version)
                    .loginEnabled(offlineViewer ? false
                            : configRepository.namedUsersExist()
                                    || !configRepository.getLdapConfig().host().isEmpty())
                    .addAllRollupConfigs(configRepository.getRollupConfigs())
                    .addAllRollupExpirationMillis(rollupExpirationMillis)
{'fraction_non_alphanumeric': 0.0790235594663639, 'fraction_numerical': 0.0023843315356230485, 'mean_word_length': 2.5466076102275017, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3309183', 'n_tokens_mistral': 4178, 'n_tokens_neox': 3997, 'n_words': 851}