James Moger
2016-01-25 252dc07d7f85cc344b5919bb7c6166ef84b2102e
commit | author | age
f13c4c 1 /*
JM 2  * Copyright 2011 gitblit.com.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
1f9dae 16 package com.gitblit.models;
5fe7df 17
46f33f 18 import java.io.IOException;
5fe7df 19 import java.io.Serializable;
JM 20
319342 21 import org.eclipse.jgit.diff.DiffEntry;
9bc17d 22 import org.eclipse.jgit.diff.DiffEntry.ChangeType;
46f33f 23 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
PM 24 import org.eclipse.jgit.errors.MissingObjectException;
25 import org.eclipse.jgit.lib.Constants;
1f9dae 26 import org.eclipse.jgit.lib.FileMode;
46f33f 27 import org.eclipse.jgit.lib.Repository;
PM 28 import org.eclipse.jgit.revwalk.RevWalk;
29
30 import com.gitblit.manager.FilestoreManager;
31 import com.gitblit.utils.JGitUtils;
5fe7df 32
d9f687 33 /**
JM 34  * PathModel is a serializable model class that represents a file or a folder,
35  * including all its metadata and associated commit id.
699e71 36  *
d9f687 37  * @author James Moger
699e71 38  *
d9f687 39  */
5fe7df 40 public class PathModel implements Serializable, Comparable<PathModel> {
JM 41
42     private static final long serialVersionUID = 1L;
155bf7 43
5fe7df 44     public final String name;
JM 45     public final String path;
46f33f 46     private final FilestoreModel filestoreItem;
5fe7df 47     public final long size;
155bf7 48     public final int mode;
eb870f 49     public final String objectId;
5fe7df 50     public final String commitId;
JM 51     public boolean isParentPath;
46f33f 52     
PM 53     public PathModel(String name, String path, FilestoreModel filestoreItem, long size, int mode, String objectId, String commitId) {
5fe7df 54         this.name = name;
JM 55         this.path = path;
46f33f 56         this.filestoreItem = filestoreItem;
PM 57         this.size = (filestoreItem == null) ? size : filestoreItem.getSize();
5fe7df 58         this.mode = mode;
eb870f 59         this.objectId = objectId;
5fe7df 60         this.commitId = commitId;
JM 61     }
155bf7 62
e5662e 63     public boolean isSymlink() {
JM 64         return FileMode.SYMLINK.equals(mode);
65     }
66
88fb67 67     public boolean isSubmodule() {
JM 68         return FileMode.GITLINK.equals(mode);
69     }
699e71 70
5fe7df 71     public boolean isTree() {
1f9dae 72         return FileMode.TREE.equals(mode);
319342 73     }
JM 74
75     public boolean isFile() {
76         return FileMode.REGULAR_FILE.equals(mode)
77                 || FileMode.EXECUTABLE_FILE.equals(mode)
78                 || (FileMode.MISSING.equals(mode) && !isSymlink() && !isSubmodule() && !isTree());
46f33f 79     }
PM 80     
81     public boolean isFilestoreItem() {
82         return filestoreItem != null;
83     }
84     
85     public String getFilestoreOid() {
86         if (filestoreItem != null) {
87             return filestoreItem.oid;
88         }
89         
90         return null;
5fe7df 91     }
155bf7 92
2a7306 93     @Override
JM 94     public int hashCode() {
95         return commitId.hashCode() + path.hashCode();
96     }
97
98     @Override
99     public boolean equals(Object o) {
100         if (o instanceof PathModel) {
101             PathModel other = (PathModel) o;
102             return this.path.equals(other.path);
103         }
104         return super.equals(o);
5fe7df 105     }
JM 106
107     @Override
108     public int compareTo(PathModel o) {
fc8426 109         boolean isTree = isTree();
JM 110         boolean otherTree = o.isTree();
111         if (isTree && otherTree) {
112             return path.compareTo(o.path);
113         } else if (!isTree && !otherTree) {
88fb67 114             if (isSubmodule() && o.isSubmodule()) {
JM 115                 return path.compareTo(o.path);
116             } else if (isSubmodule()) {
117                 return -1;
118             } else if (o.isSubmodule()) {
119                 return 1;
120             }
fc8426 121             return path.compareTo(o.path);
JM 122         } else if (isTree && !otherTree) {
123             return -1;
124         }
125         return 1;
5fe7df 126     }
9bc17d 127
d9f687 128     /**
JM 129      * PathChangeModel is a serializable class that represents a file changed in
130      * a commit.
699e71 131      *
d9f687 132      * @author James Moger
699e71 133      *
d9f687 134      */
9bc17d 135     public static class PathChangeModel extends PathModel {
2a7306 136
9bc17d 137         private static final long serialVersionUID = 1L;
2a7306 138
80d532 139         public ChangeType changeType;
699e71 140
319342 141         public int insertions;
699e71 142
319342 143         public int deletions;
699e71 144
46f33f 145         public PathChangeModel(String name, String path, FilestoreModel filestoreItem, long size, int mode, String objectId,
eb870f 146                 String commitId, ChangeType type) {
46f33f 147             super(name, path, filestoreItem, size, mode, objectId, commitId);
9bc17d 148             this.changeType = type;
319342 149         }
699e71 150
319342 151         public void update(char op) {
JM 152             switch (op) {
153             case '+':
154                 insertions++;
155                 break;
156             case '-':
157                 deletions++;
158                 break;
159             default:
160                 break;
161             }
9bc17d 162         }
2a7306 163
JM 164         @Override
165         public int hashCode() {
166             return super.hashCode();
167         }
168
169         @Override
170         public boolean equals(Object o) {
171             return super.equals(o);
172         }
319342 173
46f33f 174         public static PathChangeModel from(DiffEntry diff, String commitId, Repository repository) {
319342 175             PathChangeModel pcm;
46f33f 176             FilestoreModel filestoreItem = null;
PM 177             long size = 0;
178
179             if (repository != null) {
180                 try (RevWalk revWalk = new RevWalk(repository)) {
181                     size = revWalk.getObjectReader().getObjectSize(diff.getNewId().toObjectId(), Constants.OBJ_BLOB);
182     
183                     if (JGitUtils.isPossibleFilestoreItem(size)) {
184                         filestoreItem = JGitUtils.getFilestoreItem(revWalk.getObjectReader().open(diff.getNewId().toObjectId()));
185                     }
186                 } catch (Exception e) {
187                         e.printStackTrace();
188                 }
189             }
190             
319342 191             if (diff.getChangeType().equals(ChangeType.DELETE)) {
46f33f 192                 pcm = new PathChangeModel(diff.getOldPath(), diff.getOldPath(), filestoreItem, size, diff
319342 193                         .getNewMode().getBits(), diff.getOldId().name(), commitId, diff
JM 194                         .getChangeType());
195             } else if (diff.getChangeType().equals(ChangeType.RENAME)) {
46f33f 196                 pcm = new PathChangeModel(diff.getOldPath(), diff.getNewPath(), filestoreItem, size, diff
319342 197                         .getNewMode().getBits(), diff.getNewId().name(), commitId, diff
JM 198                         .getChangeType());
199             } else {
46f33f 200                 pcm = new PathChangeModel(diff.getNewPath(), diff.getNewPath(), filestoreItem, size, diff
319342 201                         .getNewMode().getBits(), diff.getNewId().name(), commitId, diff
JM 202                         .getChangeType());
203             }
204             return pcm;
205         }
9bc17d 206     }
5fe7df 207 }