Browse Source
The repo xml manifest parser used in RepoCommand could also be useful for others, so refactor to make it public. Also this breaks backward compatibility slightly. Change-Id: I5001bd2fe77541109fe32dbe2597a065e6ad585e Signed-off-by: Yuxuan 'fishy' Wang <fishywang@google.com>stable-4.1
Yuxuan 'fishy' Wang
10 years ago
5 changed files with 707 additions and 376 deletions
@ -0,0 +1,112 @@
|
||||
/* |
||||
* Copyright (C) 2015, Google Inc. |
||||
* and other copyright owners as documented in the project's IP log. |
||||
* |
||||
* This program and the accompanying materials are made available |
||||
* under the terms of the Eclipse Distribution License v1.0 which |
||||
* accompanies this distribution, is reproduced below, and is |
||||
* available at http://www.eclipse.org/org/documents/edl-v10.php
|
||||
* |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or |
||||
* without modification, are permitted provided that the following |
||||
* conditions are met: |
||||
* |
||||
* - Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* |
||||
* - Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following |
||||
* disclaimer in the documentation and/or other materials provided |
||||
* with the distribution. |
||||
* |
||||
* - Neither the name of the Eclipse Foundation, Inc. nor the |
||||
* names of its contributors may be used to endorse or promote |
||||
* products derived from this software without specific prior |
||||
* written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package org.eclipse.jgit.gitrepo; |
||||
|
||||
import static org.junit.Assert.assertTrue; |
||||
|
||||
import java.io.StringBufferInputStream; |
||||
import java.util.HashSet; |
||||
import java.util.Set; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
public class ManifestParserTest { |
||||
|
||||
@Test |
||||
public void testManifestParser() throws Exception { |
||||
String baseUrl = "https://git.google.com/"; |
||||
StringBuilder xmlContent = new StringBuilder(); |
||||
Set<String> results = new HashSet<String>(); |
||||
xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") |
||||
.append("<manifest>") |
||||
.append("<remote name=\"remote1\" fetch=\".\" />") |
||||
.append("<default revision=\"master\" remote=\"remote1\" />") |
||||
.append("<project path=\"foo\" name=\"") |
||||
.append("foo") |
||||
.append("\" groups=\"a,test\" />") |
||||
.append("<project path=\"bar\" name=\"") |
||||
.append("bar") |
||||
.append("\" groups=\"notdefault\" />") |
||||
.append("<project path=\"foo/a\" name=\"") |
||||
.append("a") |
||||
.append("\" groups=\"a\" />") |
||||
.append("<project path=\"b\" name=\"") |
||||
.append("b") |
||||
.append("\" groups=\"b\" />") |
||||
.append("</manifest>"); |
||||
|
||||
ManifestParser parser = new ManifestParser( |
||||
null, null, "master", baseUrl, null, null); |
||||
parser.read(new StringBufferInputStream(xmlContent.toString())); |
||||
// Unfiltered projects should have them all.
|
||||
results.clear(); |
||||
results.add("foo"); |
||||
results.add("bar"); |
||||
results.add("foo/a"); |
||||
results.add("b"); |
||||
for (RepoProject proj : parser.getProjects()) { |
||||
String msg = String.format( |
||||
"project \"%s\" should be included in unfiltered projects", |
||||
proj.path); |
||||
assertTrue(msg, results.contains(proj.path)); |
||||
results.remove(proj.path); |
||||
} |
||||
assertTrue( |
||||
"Unfiltered projects shouldn't contain any unexpected results", |
||||
results.isEmpty()); |
||||
// Filtered projects should have foo & b
|
||||
results.clear(); |
||||
results.add("foo"); |
||||
results.add("b"); |
||||
for (RepoProject proj : parser.getFilteredProjects()) { |
||||
String msg = String.format( |
||||
"project \"%s\" should be included in filtered projects", |
||||
proj.path); |
||||
assertTrue(msg, results.contains(proj.path)); |
||||
results.remove(proj.path); |
||||
} |
||||
assertTrue( |
||||
"Filtered projects shouldn't contain any unexpected results", |
||||
results.isEmpty()); |
||||
} |
||||
} |
@ -0,0 +1,351 @@
|
||||
/* |
||||
* Copyright (C) 2015, Google Inc. |
||||
* and other copyright owners as documented in the project's IP log. |
||||
* |
||||
* This program and the accompanying materials are made available |
||||
* under the terms of the Eclipse Distribution License v1.0 which |
||||
* accompanies this distribution, is reproduced below, and is |
||||
* available at http://www.eclipse.org/org/documents/edl-v10.php
|
||||
* |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or |
||||
* without modification, are permitted provided that the following |
||||
* conditions are met: |
||||
* |
||||
* - Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* |
||||
* - Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following |
||||
* disclaimer in the documentation and/or other materials provided |
||||
* with the distribution. |
||||
* |
||||
* - Neither the name of the Eclipse Foundation, Inc. nor the |
||||
* names of its contributors may be used to endorse or promote |
||||
* products derived from this software without specific prior |
||||
* written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package org.eclipse.jgit.gitrepo; |
||||
|
||||
import java.io.FileInputStream; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.net.URI; |
||||
import java.net.URISyntaxException; |
||||
import java.text.MessageFormat; |
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.HashMap; |
||||
import java.util.HashSet; |
||||
import java.util.Iterator; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.Set; |
||||
|
||||
import org.eclipse.jgit.api.errors.GitAPIException; |
||||
import org.eclipse.jgit.gitrepo.RepoProject.CopyFile; |
||||
import org.eclipse.jgit.gitrepo.internal.RepoText; |
||||
import org.eclipse.jgit.internal.JGitText; |
||||
import org.eclipse.jgit.lib.Repository; |
||||
import org.xml.sax.Attributes; |
||||
import org.xml.sax.InputSource; |
||||
import org.xml.sax.SAXException; |
||||
import org.xml.sax.XMLReader; |
||||
import org.xml.sax.helpers.DefaultHandler; |
||||
import org.xml.sax.helpers.XMLReaderFactory; |
||||
|
||||
/** |
||||
* Repo XML manifest parser. |
||||
* |
||||
* @see <a href="https://code.google.com/p/git-repo/">git-repo project page</a> |
||||
* @since 4.0 |
||||
*/ |
||||
public class ManifestParser extends DefaultHandler { |
||||
private final String filename; |
||||
private final String baseUrl; |
||||
private final String defaultBranch; |
||||
private final Repository rootRepo; |
||||
private final Map<String, String> remotes; |
||||
private final Set<String> plusGroups; |
||||
private final Set<String> minusGroups; |
||||
private List<RepoProject> projects; |
||||
private List<RepoProject> filteredProjects; |
||||
private String defaultRemote; |
||||
private String defaultRevision; |
||||
private IncludedFileReader includedReader; |
||||
private int xmlInRead; |
||||
private RepoProject currentProject; |
||||
|
||||
/** |
||||
* A callback to read included xml files. |
||||
*/ |
||||
public interface IncludedFileReader { |
||||
/** |
||||
* Read a file from the same base dir of the manifest xml file. |
||||
* |
||||
* @param path |
||||
* The relative path to the file to read |
||||
* @return the {@code InputStream} of the file. |
||||
* @throws GitAPIException |
||||
* @throws IOException |
||||
*/ |
||||
public InputStream readIncludeFile(String path) |
||||
throws GitAPIException, IOException; |
||||
} |
||||
|
||||
/** |
||||
* @param includedReader |
||||
* @param filename |
||||
* @param defaultBranch |
||||
* @param baseUrl |
||||
* @param groups |
||||
* @param rootRepo |
||||
*/ |
||||
public ManifestParser(IncludedFileReader includedReader, String filename, |
||||
String defaultBranch, String baseUrl, String groups, |
||||
Repository rootRepo) { |
||||
this.includedReader = includedReader; |
||||
this.filename = filename; |
||||
this.defaultBranch = defaultBranch; |
||||
this.rootRepo = rootRepo; |
||||
|
||||
// Strip trailing /s to match repo behavior.
|
||||
int lastIndex = baseUrl.length() - 1; |
||||
while (lastIndex >= 0 && baseUrl.charAt(lastIndex) == '/') |
||||
lastIndex--; |
||||
this.baseUrl = baseUrl.substring(0, lastIndex + 1); |
||||
|
||||
plusGroups = new HashSet<String>(); |
||||
minusGroups = new HashSet<String>(); |
||||
if (groups == null || groups.length() == 0 |
||||
|| groups.equals("default")) { //$NON-NLS-1$
|
||||
// default means "all,-notdefault"
|
||||
minusGroups.add("notdefault"); //$NON-NLS-1$
|
||||
} else { |
||||
for (String group : groups.split(",")) { //$NON-NLS-1$
|
||||
if (group.startsWith("-")) //$NON-NLS-1$
|
||||
minusGroups.add(group.substring(1)); |
||||
else |
||||
plusGroups.add(group); |
||||
} |
||||
} |
||||
|
||||
remotes = new HashMap<String, String>(); |
||||
projects = new ArrayList<RepoProject>(); |
||||
filteredProjects = new ArrayList<RepoProject>(); |
||||
} |
||||
|
||||
/** |
||||
* Read the xml file. |
||||
* |
||||
* @param inputStream |
||||
*/ |
||||
public void read(InputStream inputStream) throws IOException { |
||||
xmlInRead++; |
||||
final XMLReader xr; |
||||
try { |
||||
xr = XMLReaderFactory.createXMLReader(); |
||||
} catch (SAXException e) { |
||||
throw new IOException(JGitText.get().noXMLParserAvailable); |
||||
} |
||||
xr.setContentHandler(this); |
||||
try { |
||||
xr.parse(new InputSource(inputStream)); |
||||
} catch (SAXException e) { |
||||
IOException error = new IOException( |
||||
RepoText.get().errorParsingManifestFile); |
||||
error.initCause(e); |
||||
throw error; |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void startElement( |
||||
String uri, |
||||
String localName, |
||||
String qName, |
||||
Attributes attributes) throws SAXException { |
||||
if ("project".equals(qName)) { //$NON-NLS-1$
|
||||
currentProject = new RepoProject( |
||||
attributes.getValue("name"), //$NON-NLS-1$
|
||||
attributes.getValue("path"), //$NON-NLS-1$
|
||||
attributes.getValue("revision"), //$NON-NLS-1$
|
||||
attributes.getValue("remote"), //$NON-NLS-1$
|
||||
attributes.getValue("groups")); //$NON-NLS-1$
|
||||
} else if ("remote".equals(qName)) { //$NON-NLS-1$
|
||||
String alias = attributes.getValue("alias"); //$NON-NLS-1$
|
||||
String fetch = attributes.getValue("fetch"); //$NON-NLS-1$
|
||||
remotes.put(attributes.getValue("name"), fetch); //$NON-NLS-1$
|
||||
if (alias != null) |
||||
remotes.put(alias, fetch); |
||||
} else if ("default".equals(qName)) { //$NON-NLS-1$
|
||||
defaultRemote = attributes.getValue("remote"); //$NON-NLS-1$
|
||||
defaultRevision = attributes.getValue("revision"); //$NON-NLS-1$
|
||||
if (defaultRevision == null) |
||||
defaultRevision = defaultBranch; |
||||
} else if ("copyfile".equals(qName)) { //$NON-NLS-1$
|
||||
if (currentProject == null) |
||||
throw new SAXException(RepoText.get().invalidManifest); |
||||
currentProject.addCopyFile(new CopyFile( |
||||
rootRepo, |
||||
currentProject.path, |
||||
attributes.getValue("src"), //$NON-NLS-1$
|
||||
attributes.getValue("dest"))); //$NON-NLS-1$
|
||||
} else if ("include".equals(qName)) { //$NON-NLS-1$
|
||||
String name = attributes.getValue("name"); //$NON-NLS-1$
|
||||
InputStream is = null; |
||||
if (includedReader != null) { |
||||
try { |
||||
is = includedReader.readIncludeFile(name); |
||||
} catch (Exception e) { |
||||
throw new SAXException(MessageFormat.format( |
||||
RepoText.get().errorIncludeFile, name), e); |
||||
} |
||||
} else if (filename != null) { |
||||
int index = filename.lastIndexOf('/'); |
||||
String path = filename.substring(0, index + 1) + name; |
||||
try { |
||||
is = new FileInputStream(path); |
||||
} catch (IOException e) { |
||||
throw new SAXException(MessageFormat.format( |
||||
RepoText.get().errorIncludeFile, path), e); |
||||
} |
||||
} |
||||
if (is == null) { |
||||
throw new SAXException( |
||||
RepoText.get().errorIncludeNotImplemented); |
||||
} |
||||
try { |
||||
read(is); |
||||
} catch (IOException e) { |
||||
throw new SAXException(e); |
||||
} |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void endElement( |
||||
String uri, |
||||
String localName, |
||||
String qName) throws SAXException { |
||||
if ("project".equals(qName)) { //$NON-NLS-1$
|
||||
projects.add(currentProject); |
||||
currentProject = null; |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void endDocument() throws SAXException { |
||||
xmlInRead--; |
||||
if (xmlInRead != 0) |
||||
return; |
||||
|
||||
// Only do the following after we finished reading everything.
|
||||
Map<String, String> remoteUrls = new HashMap<String, String>(); |
||||
URI baseUri; |
||||
try { |
||||
baseUri = new URI(baseUrl); |
||||
} catch (URISyntaxException e) { |
||||
throw new SAXException(e); |
||||
} |
||||
for (RepoProject proj : projects) { |
||||
String remote = proj.remote; |
||||
if (remote == null) { |
||||
if (defaultRemote == null) { |
||||
if (filename != null) |
||||
throw new SAXException(MessageFormat.format( |
||||
RepoText.get().errorNoDefaultFilename, |
||||
filename)); |
||||
else |
||||
throw new SAXException( |
||||
RepoText.get().errorNoDefault); |
||||
} |
||||
remote = defaultRemote; |
||||
} |
||||
String remoteUrl = remoteUrls.get(remote); |
||||
if (remoteUrl == null) { |
||||
remoteUrl = baseUri.resolve(remotes.get(remote)).toString(); |
||||
if (!remoteUrl.endsWith("/")) //$NON-NLS-1$
|
||||
remoteUrl = remoteUrl + "/"; //$NON-NLS-1$
|
||||
remoteUrls.put(remote, remoteUrl); |
||||
} |
||||
proj.setUrl(remoteUrl + proj.name) |
||||
.setDefaultRevision(defaultRevision); |
||||
} |
||||
|
||||
filteredProjects.addAll(projects); |
||||
removeNotInGroup(); |
||||
removeOverlaps(); |
||||
} |
||||
|
||||
/** |
||||
* Getter for projects. |
||||
*/ |
||||
public List<RepoProject> getProjects() { |
||||
return projects; |
||||
} |
||||
|
||||
/** |
||||
* Getter for filterdProjects. |
||||
*/ |
||||
public List<RepoProject> getFilteredProjects() { |
||||
return filteredProjects; |
||||
} |
||||
|
||||
/** Remove projects that are not in our desired groups. */ |
||||
void removeNotInGroup() { |
||||
Iterator<RepoProject> iter = filteredProjects.iterator(); |
||||
while (iter.hasNext()) |
||||
if (!inGroups(iter.next())) |
||||
iter.remove(); |
||||
} |
||||
|
||||
/** Remove projects that sits in a subdirectory of any other project. */ |
||||
void removeOverlaps() { |
||||
Collections.sort(filteredProjects); |
||||
Iterator<RepoProject> iter = filteredProjects.iterator(); |
||||
if (!iter.hasNext()) |
||||
return; |
||||
RepoProject last = iter.next(); |
||||
while (iter.hasNext()) { |
||||
RepoProject p = iter.next(); |
||||
if (last.isAncestorOf(p)) |
||||
iter.remove(); |
||||
else |
||||
last = p; |
||||
} |
||||
} |
||||
|
||||
boolean inGroups(RepoProject proj) { |
||||
for (String group : minusGroups) { |
||||
if (proj.groups.contains(group)) { |
||||
// minus groups have highest priority.
|
||||
return false; |
||||
} |
||||
} |
||||
if (plusGroups.isEmpty() || plusGroups.contains("all")) { //$NON-NLS-1$
|
||||
// empty plus groups means "all"
|
||||
return true; |
||||
} |
||||
for (String group : plusGroups) { |
||||
if (proj.groups.contains(group)) |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
} |
@ -0,0 +1,214 @@
|
||||
/* |
||||
* Copyright (C) 2015, Google Inc. |
||||
* and other copyright owners as documented in the project's IP log. |
||||
* |
||||
* This program and the accompanying materials are made available |
||||
* under the terms of the Eclipse Distribution License v1.0 which |
||||
* accompanies this distribution, is reproduced below, and is |
||||
* available at http://www.eclipse.org/org/documents/edl-v10.php
|
||||
* |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or |
||||
* without modification, are permitted provided that the following |
||||
* conditions are met: |
||||
* |
||||
* - Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* |
||||
* - Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following |
||||
* disclaimer in the documentation and/or other materials provided |
||||
* with the distribution. |
||||
* |
||||
* - Neither the name of the Eclipse Foundation, Inc. nor the |
||||
* names of its contributors may be used to endorse or promote |
||||
* products derived from this software without specific prior |
||||
* written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package org.eclipse.jgit.gitrepo; |
||||
|
||||
import java.io.File; |
||||
import java.io.FileInputStream; |
||||
import java.io.FileOutputStream; |
||||
import java.io.IOException; |
||||
import java.nio.channels.FileChannel; |
||||
import java.util.ArrayList; |
||||
import java.util.Arrays; |
||||
import java.util.HashSet; |
||||
import java.util.List; |
||||
import java.util.Set; |
||||
|
||||
import org.eclipse.jgit.lib.Repository; |
||||
|
||||
/** |
||||
* The representation of a repo sub project. |
||||
* |
||||
* @see <a href="https://code.google.com/p/git-repo/">git-repo project page</a> |
||||
* @since 4.0 |
||||
*/ |
||||
public class RepoProject implements Comparable<RepoProject> { |
||||
final String name; |
||||
final String path; |
||||
final String revision; |
||||
final String remote; |
||||
final Set<String> groups; |
||||
final List<CopyFile> copyfiles; |
||||
String url; |
||||
String defaultRevision; |
||||
|
||||
/** |
||||
* The representation of a copy file configuration. |
||||
*/ |
||||
public static class CopyFile { |
||||
final Repository repo; |
||||
final String path; |
||||
final String src; |
||||
final String dest; |
||||
|
||||
/** |
||||
* @param repo |
||||
* @param path |
||||
* the path of the project containing this copyfile config. |
||||
* @param src |
||||
* @param dest |
||||
*/ |
||||
public CopyFile(Repository repo, String path, String src, String dest) { |
||||
this.repo = repo; |
||||
this.path = path; |
||||
this.src = src; |
||||
this.dest = dest; |
||||
} |
||||
|
||||
/** |
||||
* Do the copy file action. |
||||
*/ |
||||
public void copy() throws IOException { |
||||
File srcFile = new File(repo.getWorkTree(), |
||||
path + "/" + src); //$NON-NLS-1$
|
||||
File destFile = new File(repo.getWorkTree(), dest); |
||||
FileInputStream input = new FileInputStream(srcFile); |
||||
try { |
||||
FileOutputStream output = new FileOutputStream(destFile); |
||||
try { |
||||
FileChannel channel = input.getChannel(); |
||||
output.getChannel().transferFrom(channel, 0, channel.size()); |
||||
} finally { |
||||
output.close(); |
||||
} |
||||
} finally { |
||||
input.close(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @param name |
||||
* @param path |
||||
* @param revision |
||||
* @param remote |
||||
* @param groups |
||||
*/ |
||||
public RepoProject(String name, String path, String revision, |
||||
String remote, String groups) { |
||||
this.name = name; |
||||
if (path != null) |
||||
this.path = path; |
||||
else |
||||
this.path = name; |
||||
this.revision = revision; |
||||
this.remote = remote; |
||||
this.groups = new HashSet<String>(); |
||||
if (groups != null && groups.length() > 0) |
||||
this.groups.addAll(Arrays.asList(groups.split(","))); //$NON-NLS-1$
|
||||
copyfiles = new ArrayList<CopyFile>(); |
||||
} |
||||
|
||||
/** |
||||
* Set the url of the sub repo. |
||||
* |
||||
* @param url |
||||
* @return this for chaining. |
||||
*/ |
||||
public RepoProject setUrl(String url) { |
||||
this.url = url; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Set the default revision for the sub repo. |
||||
* |
||||
* @param defaultRevision |
||||
* @return this for chaining. |
||||
*/ |
||||
public RepoProject setDefaultRevision(String defaultRevision) { |
||||
this.defaultRevision = defaultRevision; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Get the revision of the sub repo. |
||||
* |
||||
* @return revision if set, or default revision. |
||||
*/ |
||||
public String getRevision() { |
||||
return revision == null ? defaultRevision : revision; |
||||
} |
||||
|
||||
/** |
||||
* Add a copy file configuration. |
||||
* |
||||
* @param copyfile |
||||
*/ |
||||
public void addCopyFile(CopyFile copyfile) { |
||||
copyfiles.add(copyfile); |
||||
} |
||||
|
||||
String getPathWithSlash() { |
||||
if (path.endsWith("/")) //$NON-NLS-1$
|
||||
return path; |
||||
else |
||||
return path + "/"; //$NON-NLS-1$
|
||||
} |
||||
|
||||
/** |
||||
* Check if this sub repo is the ancestor of another sub repo. |
||||
*/ |
||||
public boolean isAncestorOf(RepoProject that) { |
||||
return that.getPathWithSlash().startsWith(this.getPathWithSlash()); |
||||
} |
||||
|
||||
@Override |
||||
public boolean equals(Object o) { |
||||
if (o instanceof RepoProject) { |
||||
RepoProject that = (RepoProject) o; |
||||
return this.getPathWithSlash().equals(that.getPathWithSlash()); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
@Override |
||||
public int hashCode() { |
||||
return this.getPathWithSlash().hashCode(); |
||||
} |
||||
|
||||
@Override |
||||
public int compareTo(RepoProject that) { |
||||
return this.getPathWithSlash().compareTo(that.getPathWithSlash()); |
||||
} |
||||
} |
||||
|
Loading…
Reference in new issue