/** * Yobi, Project Hosting SW * * Copyright 2013 NAVER Corp. * http://yobi.io * * @author Keesun Baik * * 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 models; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.lib.Repository; import javax.persistence.*; import java.io.IOException; import java.util.ArrayList; import java.util.List; import static models.CodeRange.Side; import static models.CodeRange.Side.A; import static models.CodeRange.Side.B; /** * @author Keesun Baik */ @Entity @DiscriminatorValue("ranged") public class CodeCommentThread extends CommentThread { private static final long serialVersionUID = 1L; public static final Finder<Long, CodeCommentThread> find = new Finder<>(Long.class, CodeCommentThread.class); @Embedded public CodeRange codeRange = new CodeRange(); public String prevCommitId = StringUtils.EMPTY; public String commitId; @Transient private Boolean _isOutdated; @ManyToMany(cascade = CascadeType.ALL) public List<User> codeAuthors = new ArrayList<>(); public boolean isCommitComment() { return ObjectUtils.equals(prevCommitId, StringUtils.EMPTY); } private String unexpectedSideMessage(Side side) { return String.format("Expected '%s' or '%s', but '%s'", A, B, side); } public boolean isOnChangesOfPullRequest() { return isOnPullRequest() && StringUtils.isNotEmpty(commitId); } public boolean isOnAllChangesOfPullRequest() { return isOnChangesOfPullRequest() && StringUtils.isNotEmpty(prevCommitId); } public boolean isOutdated() throws IOException, GitAPIException { if (codeRange.startLine == null || prevCommitId == null || commitId == null) { return false; } // cache if (_isOutdated != null) { return _isOutdated; } if (!isOnPullRequest()) { return false; } if (pullRequest.mergedCommitIdFrom == null || pullRequest.mergedCommitIdTo == null) { return false; } if (isCommitComment()) { return PullRequestCommit.getByCommitId(pullRequest, commitId) == null; } String path = codeRange.path; if (path.length() > 0 && path.charAt(0) == '/') { path = path.substring(1); } Repository repository = pullRequest.getRepository(); try { if (StringUtils.isNotEmpty(prevCommitId)) { _isOutdated = !PullRequest.noChangesBetween(repository, pullRequest.mergedCommitIdFrom, repository, prevCommitId, path); } if (_isOutdated) { return _isOutdated; } _isOutdated = !PullRequest.noChangesBetween(repository, pullRequest.mergedCommitIdTo, repository, commitId, path); } catch (MissingObjectException e) { play.Logger.warn("Possible false positive of outdated detection because of missing git object: " + e.getMessage()); return true; } return _isOutdated; } }