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.index.shared; 018 019import java.util.ArrayList; 020import java.util.Arrays; 021import java.util.Collections; 022import java.util.List; 023 024import org.conqat.lib.commons.assertion.CCSMAssert; 025import org.conqat.lib.commons.collections.CollectionUtils; 026import org.conqat.lib.commons.collections.UnmodifiableList; 027 028import com.fasterxml.jackson.annotation.JsonProperty; 029 030/** 031 * A commit descriptor that additionally contains parent information. 032 */ 033public class ParentedCommitDescriptor extends CommitDescriptor { 034 035 /** Version for serialization. */ 036 private static final long serialVersionUID = 1L; 037 038 /** 039 * List of commits for which are parents of the described commit. The first 040 * commit is the direct parent, other commits are merge parents. This may also 041 * be empty for start commits. 042 */ 043 @JsonProperty("parentCommits") 044 private final List<CommitDescriptor> parentCommits = new ArrayList<>(); 045 046 public ParentedCommitDescriptor(CommitDescriptor commitDescriptor, List<CommitDescriptor> parentCommits) { 047 super(commitDescriptor.getBranchName(), commitDescriptor.getTimestamp()); 048 insertParentCommits(parentCommits); 049 } 050 051 public ParentedCommitDescriptor(CommitDescriptor commitDescriptor, CommitDescriptor... parentCommits) { 052 this(commitDescriptor, Arrays.asList(parentCommits)); 053 } 054 055 /** Inserts the parent commits. */ 056 private void insertParentCommits(List<CommitDescriptor> parentCommits) { 057 for (CommitDescriptor parent : parentCommits) { 058 CCSMAssert.isTrue(parent.getTimestamp() < getTimestamp(), 059 () -> "Can't set newer commit (" + parent + ") as parent of older commit (" + this + ")"); 060 this.parentCommits.add(new CommitDescriptor(parent.getBranchName(), parent.getTimestamp())); 061 } 062 } 063 064 /** Constructor. */ 065 public ParentedCommitDescriptor(String branchName, long timestamp, CommitDescriptor... parentCommits) { 066 super(branchName, timestamp); 067 insertParentCommits(Arrays.asList(parentCommits)); 068 } 069 070 /** Copy constructor. */ 071 public ParentedCommitDescriptor(ParentedCommitDescriptor commitDescriptor) { 072 this(commitDescriptor, commitDescriptor.parentCommits); 073 } 074 075 /** @see #parentCommits */ 076 public UnmodifiableList<CommitDescriptor> getParentCommits() { 077 return CollectionUtils.asUnmodifiable(parentCommits); 078 } 079 080 /** Returns the first parent or null. */ 081 public CommitDescriptor getFirstParentCommit() { 082 if (isStartCommit()) { 083 return null; 084 } 085 return parentCommits.get(0); 086 } 087 088 /** Returns the parent commits without the first parent commit. */ 089 public UnmodifiableList<CommitDescriptor> getOtherParentCommits() { 090 if (isStartCommit()) { 091 return CollectionUtils.asUnmodifiable(Collections.emptyList()); 092 } 093 return CollectionUtils.asUnmodifiable(parentCommits.subList(1, parentCommits.size())); 094 } 095 096 /** Returns true if this is a merge commit (i.e., has more than one parents). */ 097 public boolean isMergeCommit() { 098 return parentCommits.size() > 1; 099 } 100 101 /** Returns true if this is a start commit (i.e., has no parents). */ 102 public boolean isStartCommit() { 103 return parentCommits.isEmpty(); 104 } 105 106 /** Returns a string representation including parents. */ 107 public String toStringWithParents() { 108 StringBuilder builder = new StringBuilder(); 109 builder.append(this); 110 parentCommits.forEach(parent -> builder.append(" parent:").append(parent)); 111 return builder.toString(); 112 } 113 114}