| /* | |
| * Copyright 2011 gitblit.com. | |
| * | |
| * 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 com.gitblit.models; | |
| import java.io.IOException; | |
| import java.io.Serializable; | |
| import org.eclipse.jgit.diff.DiffEntry; | |
| import org.eclipse.jgit.diff.DiffEntry.ChangeType; | |
| import org.eclipse.jgit.errors.IncorrectObjectTypeException; | |
| import org.eclipse.jgit.errors.MissingObjectException; | |
| import org.eclipse.jgit.lib.Constants; | |
| import org.eclipse.jgit.lib.FileMode; | |
| import org.eclipse.jgit.lib.Repository; | |
| import org.eclipse.jgit.revwalk.RevWalk; | |
| import com.gitblit.manager.FilestoreManager; | |
| import com.gitblit.utils.JGitUtils; | |
| /** | |
| * PathModel is a serializable model class that represents a file or a folder, | |
| * including all its metadata and associated commit id. | |
| * | |
| * @author James Moger | |
| * | |
| */ | |
| public class PathModel implements Serializable, Comparable<PathModel> { | |
| private static final long serialVersionUID = 1L; | |
| public final String name; | |
| public final String path; | |
| private final FilestoreModel filestoreItem; | |
| public final long size; | |
| public final int mode; | |
| public final String objectId; | |
| public final String commitId; | |
| public boolean isParentPath; | |
| public PathModel(String name, String path, FilestoreModel filestoreItem, long size, int mode, String objectId, String commitId) { | |
| this.name = name; | |
| this.path = path; | |
| this.filestoreItem = filestoreItem; | |
| this.size = (filestoreItem == null) ? size : filestoreItem.getSize(); | |
| this.mode = mode; | |
| this.objectId = objectId; | |
| this.commitId = commitId; | |
| } | |
| public boolean isSymlink() { | |
| return FileMode.SYMLINK.equals(mode); | |
| } | |
| public boolean isSubmodule() { | |
| return FileMode.GITLINK.equals(mode); | |
| } | |
| public boolean isTree() { | |
| return FileMode.TREE.equals(mode); | |
| } | |
| public boolean isFile() { | |
| return FileMode.REGULAR_FILE.equals(mode) | |
| || FileMode.EXECUTABLE_FILE.equals(mode) | |
| || (FileMode.MISSING.equals(mode) && !isSymlink() && !isSubmodule() && !isTree()); | |
| } | |
| public boolean isFilestoreItem() { | |
| return filestoreItem != null; | |
| } | |
| public String getFilestoreOid() { | |
| if (filestoreItem != null) { | |
| return filestoreItem.oid; | |
| } | |
| return null; | |
| } | |
| @Override | |
| public int hashCode() { | |
| return commitId.hashCode() + path.hashCode(); | |
| } | |
| @Override | |
| public boolean equals(Object o) { | |
| if (o instanceof PathModel) { | |
| PathModel other = (PathModel) o; | |
| return this.path.equals(other.path); | |
| } | |
| return super.equals(o); | |
| } | |
| @Override | |
| public int compareTo(PathModel o) { | |
| boolean isTree = isTree(); | |
| boolean otherTree = o.isTree(); | |
| if (isTree && otherTree) { | |
| return path.compareTo(o.path); | |
| } else if (!isTree && !otherTree) { | |
| if (isSubmodule() && o.isSubmodule()) { | |
| return path.compareTo(o.path); | |
| } else if (isSubmodule()) { | |
| return -1; | |
| } else if (o.isSubmodule()) { | |
| return 1; | |
| } | |
| return path.compareTo(o.path); | |
| } else if (isTree && !otherTree) { | |
| return -1; | |
| } | |
| return 1; | |
| } | |
| /** | |
| * PathChangeModel is a serializable class that represents a file changed in | |
| * a commit. | |
| * | |
| * @author James Moger | |
| * | |
| */ | |
| public static class PathChangeModel extends PathModel { | |
| private static final long serialVersionUID = 1L; | |
| public ChangeType changeType; | |
| public int insertions; | |
| public int deletions; | |
| public PathChangeModel(String name, String path, FilestoreModel filestoreItem, long size, int mode, String objectId, | |
| String commitId, ChangeType type) { | |
| super(name, path, filestoreItem, size, mode, objectId, commitId); | |
| this.changeType = type; | |
| } | |
| public void update(char op) { | |
| switch (op) { | |
| case '+': | |
| insertions++; | |
| break; | |
| case '-': | |
| deletions++; | |
| break; | |
| default: | |
| break; | |
| } | |
| } | |
| @Override | |
| public int hashCode() { | |
| return super.hashCode(); | |
| } | |
| @Override | |
| public boolean equals(Object o) { | |
| return super.equals(o); | |
| } | |
| public static PathChangeModel from(DiffEntry diff, String commitId, Repository repository) { | |
| PathChangeModel pcm; | |
| FilestoreModel filestoreItem = null; | |
| long size = 0; | |
| if (repository != null) { | |
| try (RevWalk revWalk = new RevWalk(repository)) { | |
| size = revWalk.getObjectReader().getObjectSize(diff.getNewId().toObjectId(), Constants.OBJ_BLOB); | |
| if (JGitUtils.isPossibleFilestoreItem(size)) { | |
| filestoreItem = JGitUtils.getFilestoreItem(revWalk.getObjectReader().open(diff.getNewId().toObjectId())); | |
| } | |
| } catch (Exception e) { | |
| e.printStackTrace(); | |
| } | |
| } | |
| if (diff.getChangeType().equals(ChangeType.DELETE)) { | |
| pcm = new PathChangeModel(diff.getOldPath(), diff.getOldPath(), filestoreItem, size, diff | |
| .getNewMode().getBits(), diff.getOldId().name(), commitId, diff | |
| .getChangeType()); | |
| } else if (diff.getChangeType().equals(ChangeType.RENAME)) { | |
| pcm = new PathChangeModel(diff.getOldPath(), diff.getNewPath(), filestoreItem, size, diff | |
| .getNewMode().getBits(), diff.getNewId().name(), commitId, diff | |
| .getChangeType()); | |
| } else { | |
| pcm = new PathChangeModel(diff.getNewPath(), diff.getNewPath(), filestoreItem, size, diff | |
| .getNewMode().getBits(), diff.getNewId().name(), commitId, diff | |
| .getChangeType()); | |
| } | |
| return pcm; | |
| } | |
| } | |
| } |