/*******************************************************************************
* Copyright (c) 2013, 2014 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.orion.server.git.objects;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.orion.server.core.ProtocolConstants;
import org.eclipse.orion.server.core.resources.JSONSerializer;
import org.eclipse.orion.server.core.resources.Property;
import org.eclipse.orion.server.core.resources.ResourceShape;
import org.eclipse.orion.server.core.resources.annotations.PropertyDescription;
import org.eclipse.orion.server.core.resources.annotations.ResourceDescription;
import org.eclipse.orion.server.core.users.UserUtilities;
import org.eclipse.orion.server.git.BaseToCommitConverter;
import org.eclipse.orion.server.git.GitConstants;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@ResourceDescription(type = Blame.TYPE)
public class Blame extends GitObject {
public static final String RESOURCE = "blame"; //$NON-NLS-1$
public static final String TYPE = "Blame"; //$NON-NLS-1$
private List<String> lines = new ArrayList<String>();
private List<RevCommit> commits = new ArrayList<RevCommit>();
private String filePath = null;
private ObjectId startCommit = null;
protected JSONSerializer jsonSerializer = new JSONSerializer();
private URI blameLocation = null;
private static final ResourceShape DEFAULT_RESOURCE_SHAPE = new ResourceShape();
{
Property[] defaultProperties = new Property[] { //
new Property(ProtocolConstants.KEY_LOCATION), // super
new Property(GitConstants.KEY_CLONE), // super
new Property(ProtocolConstants.KEY_CHILDREN) };
DEFAULT_RESOURCE_SHAPE.setProperties(defaultProperties);
}
public Blame(URI cloneLocation, Repository db) {
super(cloneLocation, db);
}
/*
* Getters and Setters
*/
/**
* Add Strings of commitIds for each line
*
* @param line
*/
public void addLine(String line) {
this.lines.add(line);
}
/**
* Set the file path which will be blamed
*
* @param path
*/
public void setFilePath(String path) {
this.filePath = path;
}
/**
* Add RevCommit to needed commits
*
* @param commit
*/
public void addCommit(RevCommit commit) {
this.commits.add(commit);
}
/**
* Check is commit is in the list
*
* @param commit
* @return boolean if exists
*/
public boolean commitExists(RevCommit commit) {
return this.commits.contains(commit);
}
/**
* Get the file path for the blame object
*
* @return file path of blame object
*/
public String getFilePath() {
return this.filePath;
}
/**
* clear lines array
*/
public void clearLines() {
this.lines = new ArrayList<String>();
}
/**
* Set the Commit where the blameing will start from
*/
public void setStartCommit(ObjectId id) {
this.startCommit = id;
}
/**
* return the commit the blame function will start from
*
* @return ObjectId
*/
public ObjectId getStartCommit() {
return this.startCommit;
}
/**
* Set the URI for the blame for this file
*
* @param location
*/
public void setBlameLocation(URI location) {
this.blameLocation = location;
}
/**
* JSON Serializing
*/
@Override
public JSONObject toJSON() throws URISyntaxException {
return jsonSerializer.serialize(this, DEFAULT_RESOURCE_SHAPE);
}
@Override
protected URI getLocation() throws URISyntaxException {
return blameLocation;
}
@PropertyDescription(name = ProtocolConstants.KEY_CHILDREN)
private JSONArray getBlameJSON() throws URISyntaxException, JSONException, IOException {
if (lines.size() > 0 && commits.size() > 0) {
ArrayList<JSONArray> commitRanges = new ArrayList<JSONArray>();
JSONObject tempObj = null;
String lineId = null;
String currentCommitId = null;
for (int i = 0; i < commits.size(); i++) {
commitRanges.add(new JSONArray());
}
try {
for (int i = 0; i < lines.size(); i++) {
lineId = lines.get(i);
if (lineId != null && !lineId.equals(currentCommitId)) {
if (tempObj != null) {
tempObj.put(GitConstants.KEY_END_RANGE, i);
for (int j = 0; j < commits.size(); j++) {
if (commits.get(j).getId().getName().equals(currentCommitId)) {
commitRanges.get(j).put(tempObj);
break;
}
}
}
tempObj = new JSONObject();
tempObj.put(GitConstants.KEY_START_RANGE, i + 1);
currentCommitId = lineId;
}
}
tempObj.put(GitConstants.KEY_END_RANGE, lines.size());
for (int j = 0; j < commits.size(); j++) {
if (commits.get(j).getId().getName().equals(lineId)) {
commitRanges.get(j).put(tempObj);
break;
}
}
} catch (NullPointerException e) {
e.printStackTrace();
}
JSONArray returnJSON = new JSONArray();
RevCommit tempCommit;
PersonIdent person;
for (int i = 0; i < commitRanges.size(); i++) {
tempObj = new JSONObject();
tempCommit = commits.get(i);
person = tempCommit.getAuthorIdent();
URI commitURI = BaseToCommitConverter.getCommitLocation(cloneLocation, tempCommit.getId().getName(), BaseToCommitConverter.REMOVE_FIRST_2);
tempObj = new JSONObject();
tempObj.put(GitConstants.KEY_COMMIT_TIME, (long) tempCommit.getCommitTime() * 1000);
tempObj.put(GitConstants.KEY_AUTHOR_EMAIL, person.getEmailAddress());
tempObj.put(GitConstants.KEY_AUTHOR_NAME, person.getName());
tempObj.put(GitConstants.KEY_AUTHOR_IMAGE, UserUtilities.getImageLink(person.getEmailAddress()));
person = tempCommit.getCommitterIdent();
tempObj.put(GitConstants.KEY_COMMITTER_EMAIL, person.getEmailAddress());
tempObj.put(GitConstants.KEY_COMMITTER_NAME, person.getName());
tempObj.put(GitConstants.KEY_COMMIT, commitURI);
tempObj.put(ProtocolConstants.KEY_CHILDREN, commitRanges.get(i));
tempObj.put(GitConstants.KEY_COMMIT_MESSAGE, tempCommit.getFullMessage());
tempObj.put(ProtocolConstants.KEY_NAME, tempCommit.getId().getName());
returnJSON.put(tempObj);
}
return returnJSON;
}
return null;
}
/**
*
* JSON STRUCTURE { "Location": Blame URI "Clone Location" : Clone URI "Type": "Blame" "Children": { {
* "CommitLocation":"/gitapi/commit/2b3a36c1b2f0064216a871740bd6906b6af7434a/file/C/", "Name":"2b3a36c1b2f0064216a871740bd6906b6af7434a", "Time":1234567890,
* "AuthorName": Author Name, "AuthorEmail": Author Email, "AuthorImage": Gravatar URL, "Message": Commit Message, "Children":{ { "Start":0, "End":5 }, {
* "Start":6, "End":8 }, ... ... } }, ... ... }
*
*/
}