001/*-------------------------------------------------------------------------+
002|                                                                          |
003| Copyright 2005-2011 the ConQAT Project                                   |
004|                                                                          |
005| Licensed under the Apache License, Version 2.0 (the "License");          |
006| you may not use this file except in compliance with the License.         |
007| You may obtain a copy of the License at                                  |
008|                                                                          |
009|    http://www.apache.org/licenses/LICENSE-2.0                            |
010|                                                                          |
011| Unless required by applicable law or agreed to in writing, software      |
012| distributed under the License is distributed on an "AS IS" BASIS,        |
013| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
014| See the License for the specific language governing permissions and      |
015| limitations under the License.                                           |
016+-------------------------------------------------------------------------*/
017package org.conqat.engine.service.shared.data;
018
019import java.util.ArrayList;
020import java.util.Collections;
021import java.util.HashMap;
022import java.util.List;
023import java.util.Map;
024
025import org.conqat.engine.index.shared.GitUtils;
026import org.conqat.lib.commons.js_export.ExportToJavaScript;
027
028import com.fasterxml.jackson.annotation.JsonProperty;
029import com.teamscale.commons.lang.ToStringHelpers;
030
031/**
032 * Transport class for the branches of a project.
033 *
034 * <strong>This class is used for communication with IDE clients (via the @link
035 * {@link org.conqat.engine.service.shared.client.IdeServiceClient}, special
036 * care has to be taken when changing its signature!</strong>
037 */
038@ExportToJavaScript
039public class BranchesInfo {
040
041        /**
042         * Name of the default branch. This is called "main" branch for history reasons
043         * and we decided to keep as is, as we otherwise need migrations and new
044         * versions for the IDE plugins.
045         */
046        @JsonProperty("mainBranchName")
047        private final String mainBranchName;
048
049        /**
050         * The names of all available active branches, including the default branch, but
051         * excluding deleted and anonymous branches.
052         */
053        @JsonProperty("branchNames")
054        private final List<String> branchNames = new ArrayList<>();
055
056        /** The names of deleted/inactive branches. */
057        @JsonProperty("deletedBranches")
058        private final List<String> deletedBranches = new ArrayList<>();
059
060        /** A list of anonymous branches or an empty list if non exist. */
061        @JsonProperty("anonymousBranches")
062        private final List<String> anonymousBranches = new ArrayList<>();
063
064        /**
065         * This maps aliases to branch names. The aliases are displayed in the UI,
066         * instead of the branch name.
067         */
068        @JsonProperty("aliases")
069        private final Map<String, String> aliases = new HashMap<>();
070
071        /** Empty constructor for serialization purposes */
072        public BranchesInfo() {
073                this("", Collections.emptyList(), Collections.emptyList());
074        }
075
076        public BranchesInfo(String defaultBranchName, List<String> branchNames, List<String> deletedBranches) {
077                this.mainBranchName = defaultBranchName;
078
079                copyNonAnonymousBranches(branchNames, this.branchNames);
080                copyNonAnonymousBranches(deletedBranches, this.deletedBranches);
081        }
082
083        /**
084         * Copies all non-anonymous branches from source to target. Anonymous branches
085         * are stored in {@link #anonymousBranches}.
086         */
087        private void copyNonAnonymousBranches(List<String> sourceBranches, List<String> targetBranches) {
088                for (String branchName : sourceBranches) {
089                        if (GitUtils.isAnonymousBranchName(branchName)) {
090                                anonymousBranches.add(branchName);
091                        } else {
092                                targetBranches.add(branchName);
093                        }
094                }
095        }
096
097        /** @see #aliases */
098        public void addBranchAlias(String branch, String alias) {
099                aliases.put(branch, alias);
100        }
101
102        /** @see #aliases */
103        public Map<String, String> getAliases() {
104                return Collections.unmodifiableMap(aliases);
105        }
106
107        /** @see #mainBranchName */
108        public String getDefaultBranchName() {
109                return mainBranchName;
110        }
111
112        /** Returns the union of all branch names. */
113        public List<String> getAllBranchNames() {
114                List<String> allBranchNames = new ArrayList<>(branchNames);
115
116                // prevent NPE for deserialized objects (https://jira.cqse.eu/browse/TS-18489)
117                if (deletedBranches != null) {
118                        allBranchNames.addAll(deletedBranches);
119                }
120                if (anonymousBranches != null) {
121                        allBranchNames.addAll(anonymousBranches);
122                }
123                return allBranchNames;
124        }
125
126        @Override
127        public String toString() {
128                return ToStringHelpers.toReflectiveStringHelper(this).toString();
129        }
130}