/******************************************************************************* * Copyright (c) 2011, 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 java.util.Map.Entry; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.orion.server.core.ProtocolConstants; 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.git.BaseToRemoteConverter; import org.eclipse.orion.server.git.GitConstants; import org.eclipse.orion.server.git.servlets.GitUtils; import org.eclipse.osgi.util.NLS; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @ResourceDescription(type = Remote.TYPE) public class Remote extends GitObject { public static final String RESOURCE = "remote"; //$NON-NLS-1$ public static final String TYPE = "Remote"; //$NON-NLS-1$ private static final ResourceShape DEFAULT_RESOURCE_SHAPE_WITHOUT_CHILDREN = new ResourceShape(); private static final ResourceShape DEFAULT_RESOURCE_SHAPE = new ResourceShape(); static { Property[] defaultProperties = new Property[] { // new Property(ProtocolConstants.KEY_LOCATION), // super new Property(GitConstants.KEY_CLONE), // super new Property(ProtocolConstants.KEY_NAME), // new Property(GitConstants.KEY_URL), // new Property(GitConstants.KEY_PUSH_URL),// new Property(GitConstants.KEY_IS_GERRIT) }; DEFAULT_RESOURCE_SHAPE_WITHOUT_CHILDREN.setProperties(defaultProperties); DEFAULT_RESOURCE_SHAPE.setProperties(DEFAULT_RESOURCE_SHAPE_WITHOUT_CHILDREN.getProperties()); DEFAULT_RESOURCE_SHAPE.addProperty(new Property(ProtocolConstants.KEY_CHILDREN)); } private String name; private String newBranch; public Remote(URI cloneLocation, Repository db, String name) { super(cloneLocation, db); this.name = name; } public void setNewBranch(String newBranch) { this.newBranch = newBranch; } /** * Returns a JSON representation of this remote. */ @Override public JSONObject toJSON() throws JSONException, URISyntaxException, IOException, CoreException { return toJSON(true); } public JSONObject toJSON(boolean includeChildren) throws JSONException, URISyntaxException, IOException, CoreException { Assert.isLegal(getConfig().getSubsections(ConfigConstants.CONFIG_REMOTE_SECTION).contains(name), NLS.bind("Remote {0} not found.", name)); if (includeChildren) return jsonSerializer.serialize(this, DEFAULT_RESOURCE_SHAPE); else return jsonSerializer.serialize(this, DEFAULT_RESOURCE_SHAPE_WITHOUT_CHILDREN); } @PropertyDescription(name = GitConstants.KEY_URL) private String getUrl() { return getConfig().getString(ConfigConstants.CONFIG_REMOTE_SECTION, name, "url" /* RemoteConfig.KEY_URL */); //$NON-NLS-1$ } @PropertyDescription(name = GitConstants.KEY_PUSH_URL) private String getPushUrl() { return getConfig().getString(ConfigConstants.CONFIG_REMOTE_SECTION, name, "pushurl" /* RemoteConfig.KEY_PUSHURL */); //$NON-NLS-1$ } @PropertyDescription(name = ProtocolConstants.KEY_CHILDREN) private JSONArray getChildren() throws IOException, JSONException, URISyntaxException, CoreException { JSONArray children = new JSONArray(); boolean branchFound = false; List<Ref> refs = new ArrayList<Ref>(); String currentBranch = db.getBranch(); for (Entry<String, Ref> refEntry : db.getRefDatabase().getRefs(Constants.R_REMOTES + name + "/").entrySet()) { //$NON-NLS-1$ if (!refEntry.getValue().isSymbolic()) { Ref ref = refEntry.getValue(); String name = ref.getName(); name = Repository.shortenRefName(name).substring(Constants.DEFAULT_REMOTE_NAME.length() + 1); if (currentBranch.equals(name)) { refs.add(0, ref); } else { refs.add(ref); } } } if (newBranch != null && !newBranch.isEmpty()) { for (Ref ref : refs) { String remoteBranchName = Repository.shortenRefName(ref.getName()); remoteBranchName = remoteBranchName.substring((this.name + "/").length()); //$NON-NLS-1$ if (remoteBranchName.equals(newBranch)) { RemoteBranch remoteBranch = new RemoteBranch(cloneLocation, db, this, remoteBranchName, ref); children = new JSONArray().put(remoteBranch.toJSON()); branchFound = true; break; } } } else { for (Ref ref : refs) { String remoteBranchName = Repository.shortenRefName(ref.getName()); remoteBranchName = remoteBranchName.substring((this.name + "/").length()); //$NON-NLS-1$ RemoteBranch remoteBranch = new RemoteBranch(cloneLocation, db, this, remoteBranchName, ref); children.put(remoteBranch.toJSON()); } } if (!branchFound && newBranch != null && !newBranch.isEmpty()) { JSONObject o = new JSONObject(); // TODO: this should be a RemoteBranch boolean gerrit = getIsGerrit(); String remoteName = getName(); String fullName = gerrit ? "refs/for/" + newBranch : Constants.R_REMOTES + remoteName + "/" + newBranch; //$NON-NLS-1$ //$NON-NLS-2$ String name = gerrit ? getName() + "/for/" + newBranch : remoteName + "/" + newBranch; //$NON-NLS-1$ //$NON-NLS-2$ o.put(ProtocolConstants.KEY_NAME, name); o.put(ProtocolConstants.KEY_FULL_NAME, fullName); o.put(ProtocolConstants.KEY_TYPE, RemoteBranch.TYPE); o.put(GitConstants.KEY_URL, getConfig().getString(ConfigConstants.CONFIG_REMOTE_SECTION, remoteName, "url" /* RemoteConfig.KEY_URL */)); //$NON-NLS-1$ o.put(ProtocolConstants.KEY_LOCATION, BaseToRemoteConverter.REMOVE_FIRST_2.baseToRemoteLocation(cloneLocation, "", /* short name is {remote}/{branch} */GitUtils.encode(remoteName) + "/" + GitUtils.encode(gerrit ? fullName : newBranch))); //$NON-NLS-1$ children.put(o); } return children; } @Override public URI getLocation() throws URISyntaxException { return BaseToRemoteConverter.REMOVE_FIRST_2.baseToRemoteLocation(cloneLocation, GitUtils.encode(name), "" /* no branch name */); //$NON-NLS-1$ } @PropertyDescription(name = ProtocolConstants.KEY_NAME) public String getName() { return name; } @PropertyDescription(name = GitConstants.KEY_IS_GERRIT) public boolean getIsGerrit() { return GitUtils.isGerrit(getConfig(), this.name); } @Override public String toString() { return "Remote [name=" + name + "]"; //$NON-NLS-1$ //$NON-NLS-2$ } }