You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@labs.apache.org by gs...@apache.org on 2008/04/18 17:05:23 UTC

svn commit: r649560 [1/3] - in /labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing: ./ stringprep/

Author: gseitz
Date: Fri Apr 18 08:05:15 2008
New Revision: 649560

URL: http://svn.apache.org/viewvc?rev=649560&view=rev
Log:
LABS-126: apply Nodeprep and Resourceprep profiles to node/resource identifier

Added:
    labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/stringprep/
    labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/stringprep/NodePrep.java   (with props)
    labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/stringprep/ResourcePrep.java   (with props)
    labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/stringprep/StringPrep.java   (with props)
    labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/stringprep/StringPrepConstants.java   (with props)
    labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/stringprep/StringPrepViolationException.java   (with props)
Modified:
    labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/EntityImpl.java

Modified: labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/EntityImpl.java
URL: http://svn.apache.org/viewvc/labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/EntityImpl.java?rev=649560&r1=649559&r2=649560&view=diff
==============================================================================
--- labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/EntityImpl.java (original)
+++ labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/EntityImpl.java Fri Apr 18 08:05:15 2008
@@ -17,92 +17,110 @@
 
 package org.apache.vysper.xmpp.addressing;
 
+import org.apache.vysper.xmpp.addressing.stringprep.NodePrep;
+import org.apache.vysper.xmpp.addressing.stringprep.ResourcePrep;
+
 /**
  */
 public class EntityImpl implements Entity {
-    private String node;
-    private String domain;
-    private String resource;
-
-    public static EntityImpl parse(String entity) throws EntityFormatException {
-        String node = null;
-        String domain;
-        String resource = null;
-        if (entity == null) throw new EntityFormatException("entity must not be NULL");
-
-        if (entity.contains("@")) {
-            String[] parts = entity.split("@");
-            if (parts.length != 2) throw new EntityFormatException("entity must be of format node@domain/resource");
-            node = parts[0];
-            entity = parts[1];
-        }
-        domain = entity;
-        if (entity.contains("/")) {
-            int indexOfSlash = entity.indexOf("/");
-            domain = entity.substring(0, indexOfSlash);
-            resource = entity.substring(indexOfSlash);
-        }
-        return new EntityImpl(node, domain, resource);
-    }
-
-    public EntityImpl(String node, String domain, String resource) {
-        this.node = node;
-        this.domain = domain;
-        this.resource = resource;
-    }
-
-    public EntityImpl(Entity bareId, String resource) {
-        this.node = bareId.getNode();
-        this.domain = bareId.getDomain();
-        this.resource = resource;
-    }
-
-    public String getNode() {
-        return node;
-    }
-
-    public String getDomain() {
-        return domain;
-    }
-
-    public String getResource() {
-        return resource;
-    }
-
-    public String getFullQualifiedName() {
-        StringBuffer buffer = new StringBuffer();
-        if (node != null && !"".equals(node)) buffer.append(node).append("@");
-        buffer.append(domain);
-        if (resource != null && !"".equals(resource)) buffer.append("/").append(resource);
-        return buffer.toString();
-    }
-
-    public String getBareJID() {
-        return null;
-    }
-
-    public String getCanonicalizedName() {
-        return null;
-    }
-
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || !(o instanceof Entity)) return false;
-
-        final Entity that = (Entity) o;
-
-        if (domain != null ? !domain.equals(that.getDomain()) : that.getDomain() != null) return false;
-        if (node != null ? !node.equals(that.getNode()) : that.getNode() != null) return false;
-        if (resource != null ? !resource.equals(that.getResource()) : that.getResource() != null) return false;
-
-        return true;
-    }
-
-    public int hashCode() {
-        int result;
-        result = (node != null ? node.hashCode() : 0);
-        result = 29 * result + (domain != null ? domain.hashCode() : 0);
-        result = 29 * result + (resource != null ? resource.hashCode() : 0);
-        return result;
-    }
+	private String node;
+	private String domain;
+	private String resource;
+
+	public static EntityImpl parse(String entity) throws EntityFormatException {
+		String node = null;
+		String domain;
+		String resource = null;
+		if (entity == null)
+			throw new EntityFormatException("entity must not be NULL");
+
+		if (entity.contains("@")) {
+			String[] parts = entity.split("@");
+			if (parts.length != 2)
+				throw new EntityFormatException(
+						"entity must be of format node@domain/resource");
+			node = parts[0];
+			node = NodePrep.prepareNode(node);
+			entity = parts[1];
+		}
+		domain = entity;
+		if (entity.contains("/")) {
+			int indexOfSlash = entity.indexOf("/");
+			domain = entity.substring(0, indexOfSlash);
+			resource = entity.substring(indexOfSlash);
+			resource = ResourcePrep.prepareResource(resource);
+		}
+		return new EntityImpl(node, domain, resource);
+	}
+
+	public EntityImpl(String node, String domain, String resource) {
+		this.node = node;
+		this.domain = domain;
+		this.resource = resource;
+	}
+
+	public EntityImpl(Entity bareId, String resource) {
+		this.node = bareId.getNode();
+		this.domain = bareId.getDomain();
+		this.resource = resource;
+	}
+
+	public String getNode() {
+		return node;
+	}
+
+	public String getDomain() {
+		return domain;
+	}
+
+	public String getResource() {
+		return resource;
+	}
+
+	public String getFullQualifiedName() {
+		StringBuffer buffer = new StringBuffer();
+		if (node != null && !"".equals(node))
+			buffer.append(node).append("@");
+		buffer.append(domain);
+		if (resource != null && !"".equals(resource))
+			buffer.append("/").append(resource);
+		return buffer.toString();
+	}
+
+	public String getBareJID() {
+		return null;
+	}
+
+	public String getCanonicalizedName() {
+		return null;
+	}
+
+	public boolean equals(Object o) {
+		if (this == o)
+			return true;
+		if (o == null || !(o instanceof Entity))
+			return false;
+
+		final Entity that = (Entity) o;
+
+		if (domain != null ? !domain.equals(that.getDomain()) : that
+				.getDomain() != null)
+			return false;
+		if (node != null ? !node.equals(that.getNode())
+				: that.getNode() != null)
+			return false;
+		if (resource != null ? !resource.equals(that.getResource()) : that
+				.getResource() != null)
+			return false;
+
+		return true;
+	}
+
+	public int hashCode() {
+		int result;
+		result = (node != null ? node.hashCode() : 0);
+		result = 29 * result + (domain != null ? domain.hashCode() : 0);
+		result = 29 * result + (resource != null ? resource.hashCode() : 0);
+		return result;
+	}
 }

Added: labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/stringprep/NodePrep.java
URL: http://svn.apache.org/viewvc/labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/stringprep/NodePrep.java?rev=649560&view=auto
==============================================================================
--- labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/stringprep/NodePrep.java (added)
+++ labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/stringprep/NodePrep.java Fri Apr 18 08:05:15 2008
@@ -0,0 +1,68 @@
+package org.apache.vysper.xmpp.addressing.stringprep;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.vysper.util.annotations.RfcCompliant;
+import org.apache.vysper.util.annotations.RfcCompliant.ComplianceStatus;
+
+/**
+ * This class is used to prepare a Node Identifier for further usage.
+ * 
+ * @see RFC3920:3.3
+ * @see RFC3920:Appendix A
+ * @see http://www.ietf.org/rfc/rfc3920.txt
+ * @author Gerolf Seitz (gseitz@apache.org)
+ * 
+ */
+@RfcCompliant(rfc = "3920", section = "A", status = ComplianceStatus.PARTIAL)
+public class NodePrep extends StringPrep {
+
+	private static final StringPrep INSTANCE = new NodePrep();
+
+	/**
+	 * Applies the Nodeprep profile to the given node.
+	 * 
+	 * @param node
+	 *            the node to prepare
+	 * @return the prepared node
+	 * @throws StringPrepViolationException
+	 *             in case the Nodeprep profile can't be applied
+	 */
+	public static final String prepareNode(String node)
+			throws StringPrepViolationException {
+		return INSTANCE.prepare(node);
+	}
+
+	private NodePrep() {
+	}
+
+	@Override
+	@RfcCompliant(rfc = "3290", section = "A.3", status = ComplianceStatus.FINISHED)
+	protected Map<String, String> buildMapping() {
+		Map<String, String> mapping = new HashMap<String, String>();
+		mapping.putAll(StringPrepConstants.B_1_CommonlyMappedtoNothing);
+		mapping
+				.putAll(StringPrepConstants.B_2_MappingForCaseFoldingUsedWithKFC);
+
+		return mapping;
+	}
+
+	@Override
+	@RfcCompliant(rfc = "3290", section = "A.5", status = ComplianceStatus.FINISHED)
+	protected Set<String> buildProhibitedSet() {
+		Set<String> prohibited = super.buildProhibitedSet();
+
+		prohibited.add("\\u0022");
+		prohibited.add("\u0026");
+		prohibited.add("\u0027");
+		prohibited.add("\u002F");
+		prohibited.add("\u003A");
+		prohibited.add("\u003C");
+		prohibited.add("\u003E");
+		prohibited.add("\u0040");
+
+		return prohibited;
+	}
+}

Propchange: labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/stringprep/NodePrep.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/stringprep/ResourcePrep.java
URL: http://svn.apache.org/viewvc/labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/stringprep/ResourcePrep.java?rev=649560&view=auto
==============================================================================
--- labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/stringprep/ResourcePrep.java (added)
+++ labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/stringprep/ResourcePrep.java Fri Apr 18 08:05:15 2008
@@ -0,0 +1,66 @@
+package org.apache.vysper.xmpp.addressing.stringprep;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.vysper.util.annotations.RfcCompliant;
+import org.apache.vysper.util.annotations.RfcCompliant.ComplianceStatus;
+
+/**
+ * This class is used to prepare a Resource Identifier for further usage.
+ * 
+ * @see RFC3920:3.4
+ * @see RFC3920:Appendix B
+ * @see http://www.ietf.org/rfc/rfc3920.txt
+ * @author Gerolf Seitz (gseitz@apache.org)
+ * 
+ */
+public class ResourcePrep extends StringPrep {
+
+	private static final ResourcePrep INSTANCE = new ResourcePrep();
+
+	/**
+	 * Applies the Resourceprep profile to the given resource.
+	 * 
+	 * @param resource
+	 *            the resource to prepare
+	 * @return the prepared resource
+	 * @throws StringPrepViolationException
+	 *             in case the Resourceprep profile can't be applied
+	 */
+	public static String prepareResource(String resource)
+			throws StringPrepViolationException {
+		return INSTANCE.prepare(resource);
+	}
+
+	private ResourcePrep() {
+
+	}
+
+	@Override
+	@RfcCompliant(rfc = "3290", section = "B.3", status = ComplianceStatus.FINISHED)
+	protected Map<String, String> buildMapping() {
+		return StringPrepConstants.B_1_CommonlyMappedtoNothing;
+	}
+
+	@Override
+	@RfcCompliant(rfc = "3290", section = "B.5", status = ComplianceStatus.FINISHED)
+	protected Set<String> buildProhibitedSet() {
+		Set<String> set = new HashSet<String>();
+		set.addAll(StringPrepConstants.C_1_2_NonAsciiSpaceCharacters);
+		set.addAll(StringPrepConstants.C_2_1_AsciiControlCharacters);
+		set.addAll(StringPrepConstants.C_2_2_NonAsciiControlCharacters);
+		set.addAll(StringPrepConstants.C_3_PrivateUse);
+		set.addAll(StringPrepConstants.C_4_NonCharacterCodePoints);
+		set.addAll(StringPrepConstants.C_5_SurrogateCodes);
+		set.addAll(StringPrepConstants.C_6_InappropriateForPlainText);
+		set
+				.addAll(StringPrepConstants.C_7_InappropriateForCanonicalRepresentation);
+		set
+				.addAll(StringPrepConstants.C_8_ChangeDisplayPropertiesOrAreDeprecated);
+		set.addAll(StringPrepConstants.C_9_TaggingCharacters);
+
+		return set;
+	}
+}

Propchange: labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/stringprep/ResourcePrep.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/stringprep/StringPrep.java
URL: http://svn.apache.org/viewvc/labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/stringprep/StringPrep.java?rev=649560&view=auto
==============================================================================
--- labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/stringprep/StringPrep.java (added)
+++ labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/stringprep/StringPrep.java Fri Apr 18 08:05:15 2008
@@ -0,0 +1,139 @@
+package org.apache.vysper.xmpp.addressing.stringprep;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.vysper.util.annotations.RfcCompliant;
+
+/**
+ * Use this class to prepare a String according to the Stringprep profile. The
+ * methods {@link #buildMapping()} and {@link #buildProhibitedSet()} can be
+ * overridden to modify the behavior of the Stringprep check.
+ * 
+ * @see http://www.ietf.org/rfc/rfc3454.txt
+ * 
+ * @author Gerolf Seitz (gseitz@apache.org)
+ * 
+ */
+@RfcCompliant(rfc = "3454")
+public class StringPrep {
+
+	private Map<String, String> mapping;
+	private Set<String> prohibited;
+
+	/**
+	 * Construct.
+	 */
+	public StringPrep() {
+		mapping = buildMapping();
+		prohibited = buildProhibitedSet();
+	}
+
+	/**
+	 * Prepares the given {@link String} according to the Stringprep
+	 * specification.
+	 * 
+	 * @param str
+	 *            the string to prepare
+	 * @return the prepared {@link String}
+	 * @throws StringPrepViolationException
+	 *             in case the {@link String} cannot be prepared
+	 */
+	public String prepare(String str) throws StringPrepViolationException {
+		// 1. map -> RFC3454:3
+		for (int i = 0; i < str.length(); i++) {
+			String codePoint = codePointAt(str, i);
+			if (mapping.containsKey(codePoint)) {
+				str = str.replace(codePoint, mapping.get(codePoint));
+			}
+		}
+		// TODO: 2. normalize -> RFC3454:4
+
+		// 3. prohibit -> RFC3454:5
+		for (int i = 0; i < str.length(); i++) {
+			String codePoint = codePointAt(str, i);
+			if (prohibited.contains(codePoint)) {
+				throw new StringPrepViolationException(String.format(
+						"character '%s' prohibited!", codePoint));
+			}
+		}
+
+		// 4. check bidi -> RFC3454:6
+		boolean containsRAndAlCat = false;
+		boolean containsLCat = false;
+		for (int i = 0; i < str.length()
+				&& NAND(containsRAndAlCat, containsLCat); i++) {
+			String codePoint = codePointAt(str, i);
+			containsRAndAlCat |= StringPrepConstants.D_1_CharactersWithBiDiPropertiesRorAl
+					.contains(codePoint);
+			containsLCat |= StringPrepConstants.D_2_CharactersWithBiDiPropertyL
+					.contains(codePoint);
+		}
+		if (containsRAndAlCat && containsLCat) {
+			throw new StringPrepViolationException("invalid bidi sequence");
+		}
+		if (containsRAndAlCat) {
+			if (!StringPrepConstants.D_1_CharactersWithBiDiPropertiesRorAl
+					.contains(codePointAt(str, 0))
+					|| !StringPrepConstants.D_1_CharactersWithBiDiPropertiesRorAl
+							.contains(codePointAt(str, str.length() - 1))) {
+				throw new StringPrepViolationException("invalid bidi sequence");
+			}
+		}
+
+		return str;
+	}
+
+	/**
+	 * Override this method and return a custom map of character mappings to
+	 * alter the Stringprep behavior.
+	 * 
+	 * @return a {@link Map<String, String>} containing all character mappings
+	 */
+	protected Map<String, String> buildMapping() {
+		Map<String, String> mapping = new HashMap<String, String>();
+		mapping.putAll(StringPrepConstants.B_1_CommonlyMappedtoNothing);
+		mapping
+				.putAll(StringPrepConstants.B_2_MappingForCaseFoldingUsedWithKFC);
+		mapping
+				.putAll(StringPrepConstants.B_3_MappingForCaseFoldingWithNoNormalization);
+
+		return mapping;
+	}
+
+	/**
+	 * Override this method and return a custom set of prohibited characters to
+	 * alter the Stringprep behavior.
+	 * 
+	 * @return a {@link Set<String>} containing all characters that are
+	 *         prohibited
+	 */
+	protected Set<String> buildProhibitedSet() {
+		Set<String> prohibited = new HashSet<String>();
+		prohibited.addAll(StringPrepConstants.C_1_1_AsciiSpaceCharacters);
+		prohibited.addAll(StringPrepConstants.C_1_2_NonAsciiSpaceCharacters);
+		prohibited.addAll(StringPrepConstants.C_2_1_AsciiControlCharacters);
+		prohibited.addAll(StringPrepConstants.C_2_2_NonAsciiControlCharacters);
+		prohibited.addAll(StringPrepConstants.C_3_PrivateUse);
+		prohibited.addAll(StringPrepConstants.C_4_NonCharacterCodePoints);
+		prohibited.addAll(StringPrepConstants.C_5_SurrogateCodes);
+		prohibited.addAll(StringPrepConstants.C_6_InappropriateForPlainText);
+		prohibited
+				.addAll(StringPrepConstants.C_7_InappropriateForCanonicalRepresentation);
+		prohibited
+				.addAll(StringPrepConstants.C_8_ChangeDisplayPropertiesOrAreDeprecated);
+		prohibited.addAll(StringPrepConstants.C_9_TaggingCharacters);
+		return prohibited;
+	}
+
+	private String codePointAt(String node, int i) {
+		int c = node.codePointAt(i);
+		return new String(Character.toChars(c));
+	}
+
+	private boolean NAND(boolean a, boolean b) {
+		return (!(a || b)) || (a ^ b);
+	}
+}

Propchange: labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/stringprep/StringPrep.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@labs.apache.org
For additional commands, e-mail: commits-help@labs.apache.org