assertTrue("The a submodule should exist", a);
}
+ @Test
+ public void testIncludeTag() throws Exception {
+ Repository localDb = createWorkRepository();
+ Repository tempDb = createWorkRepository();
+
+ StringBuilder xmlContent = new StringBuilder();
+ xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
+ .append("<manifest>")
+ .append("<include name=\"_include.xml\" />")
+ .append("<default revision=\"master\" remote=\"remote1\" />")
+ .append("</manifest>");
+ JGitTestUtil.writeTrashFile(
+ tempDb, "manifest.xml", xmlContent.toString());
+
+ xmlContent = new StringBuilder();
+ 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(defaultUri)
+ .append("\" />")
+ .append("</manifest>");
+ JGitTestUtil.writeTrashFile(
+ tempDb, "_include.xml", xmlContent.toString());
+
+ RepoCommand command = new RepoCommand(localDb);
+ command
+ .setPath(tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
+ .setURI(rootUri)
+ .call();
+ File hello = new File(localDb.getWorkTree(), "foo/hello.txt");
+ assertTrue("submodule should be checked out", hello.exists());
+ BufferedReader reader = new BufferedReader(new FileReader(hello));
+ String content = reader.readLine();
+ reader.close();
+ assertEquals("submodule content should be as expected",
+ "master world", content);
+ }
+
private void resolveRelativeUris() {
// Find the longest common prefix ends with "/" as rootUri.
defaultUri = defaultDb.getDirectory().toURI().toString();
private PersonIdent author;
private RemoteReader callback;
private InputStream inputStream;
+ private IncludedFileReader includedReader;
private List<Project> bareProjects;
private Git git;
* @return the file content.
* @throws GitAPIException
* @throws IOException
+ * @since 3.5
*/
public byte[] readFile(String uri, String ref, String path)
throws GitAPIException, IOException;
}
}
+ /**
+ * A callback to read included xml files.
+ *
+ * @since 3.5
+ */
+ 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;
+ }
+
private static class CopyFile {
final Repository repo;
final String path;
private static class XmlManifest extends DefaultHandler {
private final RepoCommand command;
- private final InputStream inputStream;
private final String filename;
private final String baseUrl;
private final Map<String, String> remotes;
private List<Project> projects;
private String defaultRemote;
private String defaultRevision;
+ private IncludedFileReader includedReader;
+ private int xmlInRead;
private Project currentProject;
- XmlManifest(RepoCommand command, InputStream inputStream,
+ XmlManifest(RepoCommand command, IncludedFileReader includedReader,
String filename, String baseUrl, String groups) {
this.command = command;
- this.inputStream = inputStream;
+ this.includedReader = includedReader;
this.filename = filename;
// Strip trailing /s to match repo behavior.
}
}
- void read() throws IOException {
+ void read(InputStream inputStream) throws IOException {
+ xmlInRead++;
final XMLReader xr;
try {
xr = XMLReaderFactory.createXMLReader();
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");
+ 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 endDocument() throws SAXException {
+ xmlInRead--;
+ if (xmlInRead != 0)
+ return;
+ // Only do the following after we finished reading everything.
if (defaultRemote == null) {
if (filename != null)
throw new SAXException(MessageFormat.format(
return this;
}
+ /**
+ * Set the IncludedFileReader callback.
+ *
+ * @param reader
+ * @return this command
+ */
+ public RepoCommand setIncludedFileReader(IncludedFileReader reader) {
+ this.includedReader = reader;
+ return this;
+ }
+
@Override
public RevCommit call() throws GitAPIException {
try {
git = new Git(repo);
XmlManifest manifest = new XmlManifest(
- this, inputStream, path, uri, groups);
+ this, includedReader, path, uri, groups);
try {
- manifest.read();
+ manifest.read(inputStream);
} catch (IOException e) {
throw new ManifestErrorException(e);
}