/**
 * 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 javax.annotation.Nullable;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

import java.io.IOException;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Repository;

import static models.CodeRange.Side;
import static models.CodeRange.Side.*;

/**
 * @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
    @Nullable
    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 mergedRepository = pullRequest.getMergedRepository();

        if (StringUtils.isNotEmpty(prevCommitId)) {
            _isOutdated = !PullRequest.noChangesBetween(mergedRepository,
                pullRequest.mergedCommitIdFrom, mergedRepository, prevCommitId, path);
        }

        if (_isOutdated) {
            return _isOutdated;
        }

        _isOutdated = !PullRequest.noChangesBetween(mergedRepository,
            pullRequest.mergedCommitIdTo, mergedRepository, commitId, path);

        return _isOutdated;
    }
}

@@ -956,32 +956,87 @@
 itAPIException;%0A
+import org.eclipse.jgit.errors.MissingObjectException;%0A
 import org.eclip
@@ -3089,24 +3089,42 @@
 ository();%0A%0A
+        try %7B%0A    
         if (
@@ -3159,24 +3159,28 @@
 ommitId)) %7B%0A
+    
             
@@ -3249,32 +3249,36 @@
                 
+   
+ 
 pullRequest.merg
@@ -3336,35 +3336,42 @@
 h);%0A        
-%7D%0A%0A
+    %7D%0A%0A   
         
 if (_isOutda
@@ -3350,32 +3350,33 @@
   %7D%0A%0A           
+ 
 if (_isOutdated)
@@ -3374,24 +3374,28 @@
 Outdated) %7B%0A
+    
             
@@ -3414,35 +3414,43 @@
 tdated;%0A        
+   
+ 
 %7D%0A%0A
+    
         _isOutda
@@ -3507,32 +3507,36 @@
 ry,%0A            
+   
+ 
 pullRequest.merg
@@ -3583,16 +3583,224 @@
 , path);
+%0A        %7D catch (MissingObjectException e) %7B%0A            play.Logger.warn(%22Possible false positive of outdated detection because of missing git object: %22 + e.getMessage());%0A            return true;%0A        %7D
 %0A%0A      

Fix missing object exception during outdated detecting