git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Nigel Magnay <nigel.magnay@gmail.com>
To: Git ML <git@vger.kernel.org>
Subject: [JGIT PATCH] 1/2: Externalizable items
Date: Mon, 16 Feb 2009 16:45:55 +0000	[thread overview]
Message-ID: <320075ff0902160845m264f78cdh8dc5307b24f4c3ed@mail.gmail.com> (raw)

Make parts of jgit externalizable, so that they can be marshalled over
the wire or onto disk,
using formats from git mailing list.

Signed-off-by: Nigel Magnay <nigel.magnay@gmail.com>
---
 .../src/org/spearce/jgit/lib/ObjectId.java         |   31 ++++-
 .../src/org/spearce/jgit/transport/RefSpec.java    |   77 +++++++----
 .../org/spearce/jgit/transport/RemoteConfig.java   |  142 +++++++++++++++++++-
 .../src/org/spearce/jgit/transport/URIish.java     |   31 ++++-
 4 files changed, 252 insertions(+), 29 deletions(-)

diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectId.java
b/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectId.java
index 52ce0d4..1385325 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectId.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectId.java
@@ -38,6 +38,10 @@

 package org.spearce.jgit.lib;

+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
 import java.io.UnsupportedEncodingException;

 import org.spearce.jgit.util.NB;
@@ -45,7 +49,7 @@
 /**
  * A SHA-1 abstraction.
  */
-public class ObjectId extends AnyObjectId {
+public class ObjectId extends AnyObjectId implements Externalizable {
 	private static final ObjectId ZEROID;

 	private static final String ZEROID_STR;
@@ -56,6 +60,13 @@
 	}

 	/**
+	 * Empty constructor, for Externalizable.
+	 */
+	public ObjectId() {
+		// For Externalizable
+	}
+	
+	/**
 	 * Get the special all-null ObjectId.
 	 *
 	 * @return the all-null ObjectId, often used to stand-in for no object.
@@ -269,4 +280,22 @@ protected ObjectId(final AnyObjectId src) {
 	public ObjectId toObjectId() {
 		return this;
 	}
+
+	public void readExternal(ObjectInput in) throws IOException,
+			ClassNotFoundException {
+		byte[] sha1 = new byte[20];
+		in.read(sha1);
+		
+		w1 = NB.decodeInt32(sha1, 0);
+		w2 = NB.decodeInt32(sha1, 4);
+		w3 = NB.decodeInt32(sha1, 8);
+		w4 = NB.decodeInt32(sha1, 12);
+		w5 = NB.decodeInt32(sha1, 16);
+	}
+
+	public void writeExternal(ObjectOutput out) throws IOException {
+		byte[] sha1 = new byte[20];
+		copyRawTo(sha1, 0);
+		out.write(sha1);
+	}
 }
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/RefSpec.java
b/org.spearce.jgit/src/org/spearce/jgit/transport/RefSpec.java
index 521110b..0ee89b0 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/RefSpec.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/RefSpec.java
@@ -37,6 +37,11 @@

 package org.spearce.jgit.transport;

+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
 import org.spearce.jgit.lib.Constants;
 import org.spearce.jgit.lib.Ref;

@@ -46,7 +51,7 @@
  * A ref specification provides matching support and limited rules to rewrite a
  * reference in one repository to another reference in another repository.
  */
-public class RefSpec {
+public class RefSpec implements Externalizable {
 	/**
 	 * Suffix for wildcard ref spec component, that indicate matching all refs
 	 * with specified prefix.
@@ -109,30 +114,7 @@ public RefSpec() {
 	 *             the specification is invalid.
 	 */
 	public RefSpec(final String spec) {
-		String s = spec;
-		if (s.startsWith("+")) {
-			force = true;
-			s = s.substring(1);
-		}
-
-		final int c = s.indexOf(':');
-		if (c == 0) {
-			s = s.substring(1);
-			if (isWildcard(s))
-				throw new IllegalArgumentException("Invalid wildcards " + spec);
-			dstName = s;
-		} else if (c > 0) {
-			srcName = s.substring(0, c);
-			dstName = s.substring(c + 1);
-			if (isWildcard(srcName) && isWildcard(dstName))
-				wildcard = true;
-			else if (isWildcard(srcName) || isWildcard(dstName))
-				throw new IllegalArgumentException("Invalid wildcards " + spec);
-		} else {
-			if (isWildcard(s))
-				throw new IllegalArgumentException("Invalid wildcards " + spec);
-			srcName = s;
-		}
+		initializeFromString(spec);
 	}

 	/**
@@ -161,6 +143,42 @@ private RefSpec(final RefSpec p) {
 	}

 	/**
+	 * Initialize the ref specification from a string.
+	 *
+	 * @param spec
+	 *            string describing the specification.
+	 * @throws IllegalArgumentException
+	 *             the specification is invalid.
+	 */
+	private void initializeFromString(final String spec) {
+		srcName = null;
+		String s = spec;
+		if (s.startsWith("+")) {
+			force = true;
+			s = s.substring(1);
+		}
+
+		final int c = s.indexOf(':');
+		if (c == 0) {
+			s = s.substring(1);
+			if (isWildcard(s))
+				throw new IllegalArgumentException("Invalid wildcards " + spec);
+			dstName = s;
+		} else if (c > 0) {
+			srcName = s.substring(0, c);
+			dstName = s.substring(c + 1);
+			if (isWildcard(srcName) && isWildcard(dstName))
+				wildcard = true;
+			else if (isWildcard(srcName) || isWildcard(dstName))
+				throw new IllegalArgumentException("Invalid wildcards " + spec);
+		} else {
+			if (isWildcard(s))
+				throw new IllegalArgumentException("Invalid wildcards " + spec);
+			srcName = s;
+		}
+	}
+	
+	/**
 	 * Check if this specification wants to forcefully update the destination.
 	 *
 	 * @return true if this specification asks for updates without merge tests.
@@ -421,4 +439,13 @@ public String toString() {
 		}
 		return r.toString();
 	}
+
+	public void readExternal(ObjectInput in) throws IOException,
+			ClassNotFoundException {
+		initializeFromString(in.readUTF());	
+	}
+
+	public void writeExternal(ObjectOutput out) throws IOException {
+		out.writeUTF(toString());
+	}
 }
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/RemoteConfig.java
b/org.spearce.jgit/src/org/spearce/jgit/transport/RemoteConfig.java
index 5bbf664..22443b4 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/RemoteConfig.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/RemoteConfig.java
@@ -38,10 +38,17 @@

 package org.spearce.jgit.transport;

+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;

 import org.spearce.jgit.lib.RepositoryConfig;

@@ -53,7 +60,7 @@
  * describing how refs should be transferred between this repository and the
  * remote repository.
  */
-public class RemoteConfig {
+public class RemoteConfig implements Externalizable {
 	private static final String SECTION = "remote";

 	private static final String KEY_URL = "url";
@@ -166,6 +173,17 @@ public RemoteConfig(final RepositoryConfig rc,
final String remoteName)
 	}

 	/**
+	 * Construct an empty remote config.
+	 */
+	public RemoteConfig() {
+		uris = new ArrayList<URIish>();
+		fetch = new ArrayList<RefSpec>();
+		push = new ArrayList<RefSpec>();
+		uploadpack = DEFAULT_UPLOAD_PACK;
+		receivepack = DEFAULT_RECEIVE_PACK;
+	}
+	
+	/**
 	 * Update this remote's definition within the configuration.
 	 *
 	 * @param rc
@@ -382,4 +400,126 @@ public TagOpt getTagOpt() {
 	public void setTagOpt(final TagOpt option) {
 		tagopt = option != null ? option : TagOpt.AUTO_FOLLOW;
 	}
+
+	private Map<String, Collection<String>> toMap() {
+		Map<String, Collection<String>> map = new HashMap<String,
Collection<String>>();
+		
+		if (uris.size() > 0) {
+			Collection<String> values = new ArrayList<String>();
+			for (URIish uri : uris) {
+				values.add(uri.toPrivateString());
+			}
+			map.put(KEY_URL, values);
+		}
+		
+		if (fetch.size() > 0) {
+			Collection<String> values = new ArrayList<String>();
+			for (RefSpec refspec : fetch) {
+				values.add(refspec.toString());
+			}
+			map.put(KEY_FETCH, values);
+		}
+		
+		if (push.size() > 0) {
+			Collection<String> values = new ArrayList<String>();
+			for (RefSpec refspec : push) {
+				values.add(refspec.toString());
+			}
+			map.put(KEY_PUSH, values);
+		}
+		
+		Collection<String> uploads = new ArrayList<String>(1);
+		uploads.add(uploadpack);
+		map.put(KEY_UPLOADPACK, uploads);
+		
+		Collection<String> receives = new ArrayList<String>(1);
+		receives.add(uploadpack);
+		map.put(KEY_RECEIVEPACK, receives);
+		
+		Collection<String> tag = new ArrayList<String>(1);
+		tag.add(tagopt.option());
+		map.put(KEY_TAGOPT, tag);
+		
+		
+		return map;
+	}
+
+	private void fromMap(Map<String, Collection<String>> map)
+			throws URISyntaxException {
+		for (Map.Entry<String, Collection<String>> entry : map.entrySet()) {
+			String key = entry.getKey();
+
+			if (key.equals(KEY_URL)) {
+				for (String value : entry.getValue()) {
+					uris.add(new URIish(value));
+				}
+			} else if (key.equals(KEY_FETCH)) {
+				for (String value : entry.getValue()) {
+					fetch.add(new RefSpec(value));
+				}
+			} else if (key.equals(KEY_PUSH)) {
+				for (String value : entry.getValue()) {
+					push.add(new RefSpec(value));
+				}
+			} else if (key.equals(KEY_UPLOADPACK)) {
+				for (String value : entry.getValue()) {
+					uploadpack = value;
+				}
+			} else if (key.equals(KEY_RECEIVEPACK)) {
+				for (String value : entry.getValue()) {
+					receivepack = value;
+				}
+			} else if (key.equals(KEY_TAGOPT)) {
+				for (String value : entry.getValue()) {
+					tagopt = TagOpt.fromOption(value);
+				}
+			}
+		}
+	}
+
+	public void readExternal(ObjectInput in) throws IOException,
+			ClassNotFoundException {
+		name = in.readUTF();
+		int items = in.readInt();
+
+		Map<String, Collection<String>> map = new HashMap<String,
Collection<String>>();
+		for (int i = 0; i < items; i++) {
+			String key = in.readUTF();
+			String value = in.readUTF();
+
+			Collection<String> values = map.get(key);
+			if (values == null) {
+				values = new ArrayList<String>();
+				map.put(key, values);
+			}
+
+			values.add(value);
+		}
+
+		try {
+			fromMap(map);
+		} catch (URISyntaxException ex) {
+			throw new IOException("Problem reading RemoteConfig map");
+		}
+	}
+
+	public void writeExternal(ObjectOutput out) throws IOException {
+		Map<String, Collection<String>> map = toMap();
+		
+		int size = 0;
+		
+		for (Map.Entry<String, Collection<String>> entry : map.entrySet()) {
+			size += entry.getValue().size();
+		}
+		
+		out.writeUTF(name);
+		out.writeInt(size);
+
+		for (Map.Entry<String, Collection<String>> entry : map.entrySet()) {
+			for (String value : entry.getValue()) {
+				out.writeUTF(entry.getKey());
+				out.writeUTF(value);
+			}
+		}
+	}
 }
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/URIish.java
b/org.spearce.jgit/src/org/spearce/jgit/transport/URIish.java
index b86e00c..05e24b2 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/URIish.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/URIish.java
@@ -38,6 +38,10 @@

 package org.spearce.jgit.transport;

+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.regex.Matcher;
@@ -49,7 +53,7 @@
  * RFC 2396 URI's is that no URI encoding/decoding ever takes place. A space or
  * any special character is written as-is.
  */
-public class URIish {
+public class URIish implements Externalizable {
 	private static final Pattern FULL_URI = Pattern
 			.compile("^(?:([a-z][a-z0-9+-]+)://(?:([^/]+?)(?::([^/]+?))?@)?(?:([^/]+?))?(?::(\\d+))?)?((?:[A-Za-z]:)?/.+)$");

@@ -75,7 +79,17 @@
 	 * @throws URISyntaxException
 	 */
 	public URIish(String s) throws URISyntaxException {
-		s = s.replace('\\', '/');
+		initializeFromString(s);
+	}
+	
+	/**
+	 * Set fields from string based URI.
+	 *
+	 * @param s
+	 * @throws URISyntaxException
+	 */
+	private void initializeFromString(String s)  throws URISyntaxException {
+	    s = s.replace('\\', '/');
 		Matcher matcher = FULL_URI.matcher(s);
 		if (matcher.matches()) {
 			scheme = matcher.group(1);
@@ -357,4 +371,17 @@ private String format(final boolean includePassword) {

 		return r.toString();
 	}
+
+	public void readExternal(ObjectInput in) throws IOException,
+			ClassNotFoundException {
+	    try {
+			initializeFromString(in.readUTF());
+		} catch (URISyntaxException e) {
+			throw new IOException("Incorrect format URI");
+		}
+	}
+
+	public void writeExternal(ObjectOutput out) throws IOException {
+		out.writeUTF(format(true));
+	}
 }
-- 
1.6.0.2

             reply	other threads:[~2009-02-16 16:47 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-02-16 16:45 Nigel Magnay [this message]
2009-02-16 16:59 ` [JGIT PATCH] 1/2: Externalizable items Johannes Schindelin
2009-02-16 17:10   ` Nigel Magnay
2009-02-16 17:20 ` Shawn O. Pearce
2009-02-16 18:09   ` Nigel Magnay
2009-02-16 18:16     ` Shawn O. Pearce

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=320075ff0902160845m264f78cdh8dc5307b24f4c3ed@mail.gmail.com \
    --to=nigel.magnay@gmail.com \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).