diff --git a/src/main/java/org/springframework/hateoas/hal/HalLinkDiscoverer.java b/src/main/java/org/springframework/hateoas/hal/HalLinkDiscoverer.java
new file mode 100644
index 00000000..217bfb57
--- /dev/null
+++ b/src/main/java/org/springframework/hateoas/hal/HalLinkDiscoverer.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.hateoas.hal;
+
+import org.springframework.hateoas.LinkDiscoverer;
+import org.springframework.hateoas.core.JsonPathLinkDiscoverer;
+
+/**
+ * {@link LinkDiscoverer} implementation based on HAL link structure.
+ *
+ * @author Oliver Gierke
+ */
+public class HalLinkDiscoverer extends JsonPathLinkDiscoverer {
+
+ public HalLinkDiscoverer() {
+ super("$_links..%s.href");
+ }
+}
diff --git a/src/test/java/org/springframework/hateoas/core/AbstractLinkDiscovererUnitTests.java b/src/test/java/org/springframework/hateoas/core/AbstractLinkDiscovererUnitTests.java
new file mode 100644
index 00000000..a8763d97
--- /dev/null
+++ b/src/test/java/org/springframework/hateoas/core/AbstractLinkDiscovererUnitTests.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.hateoas.core;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.List;
+
+import org.junit.Test;
+import org.springframework.hateoas.Link;
+import org.springframework.hateoas.LinkDiscoverer;
+
+/**
+ * Base class for unit tests for {@link LinkDiscoverer} implementations.
+ *
+ * @author Oliver Gierke
+ */
+public abstract class AbstractLinkDiscovererUnitTests {
+
+ @Test
+ public void findsSingleLink() {
+
+ assertThat(getDiscoverer().findLinkWithRel("self", getInputString()), is(new Link("selfHref")));
+
+ List links = getDiscoverer().findLinksWithRel("self", getInputString());
+ assertThat(links, hasSize(1));
+ assertThat(links, hasItem(new Link("selfHref")));
+ }
+
+ @Test
+ public void findsFirstLink() {
+
+ assertThat(getDiscoverer().findLinkWithRel("relation", getInputString()), is(new Link("firstHref", "relation")));
+ }
+
+ @Test
+ public void findsAllLinks() {
+
+ List links = getDiscoverer().findLinksWithRel("relation", getInputString());
+ assertThat(links, hasSize(2));
+ assertThat(links, hasItems(new Link("firstHref", "relation"), new Link("secondHref", "relation")));
+ }
+
+ @Test
+ public void returnsForInexistingLink() {
+ assertThat(getDiscoverer().findLinkWithRel("something", getInputString()), is(nullValue()));
+ }
+
+ @Test
+ public void returnsForInxistingLinkFromInputStream() throws Exception {
+
+ InputStream inputStream = new ByteArrayInputStream(getInputString().getBytes("UTF-8"));
+ assertThat(getDiscoverer().findLinkWithRel("something", inputStream), is(nullValue()));
+ }
+
+ /**
+ * Return the {@link LinkDiscoverer} to be tested.
+ *
+ * @return
+ */
+ protected abstract LinkDiscoverer getDiscoverer();
+
+ /**
+ * Return the JSON structure we expect to find the links in.
+ *
+ * @return
+ */
+ protected abstract String getInputString();
+}
diff --git a/src/test/java/org/springframework/hateoas/core/DefaultLinkDiscovererUnitTest.java b/src/test/java/org/springframework/hateoas/core/DefaultLinkDiscovererUnitTest.java
index 4f770468..1260b568 100644
--- a/src/test/java/org/springframework/hateoas/core/DefaultLinkDiscovererUnitTest.java
+++ b/src/test/java/org/springframework/hateoas/core/DefaultLinkDiscovererUnitTest.java
@@ -15,15 +15,6 @@
*/
package org.springframework.hateoas.core;
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.util.List;
-
-import org.junit.Test;
-import org.springframework.hateoas.Link;
import org.springframework.hateoas.LinkDiscoverer;
/**
@@ -31,7 +22,7 @@ import org.springframework.hateoas.LinkDiscoverer;
*
* @author Oliver Gierke
*/
-public class DefaultLinkDiscovererUnitTest {
+public class DefaultLinkDiscovererUnitTest extends AbstractLinkDiscovererUnitTests {
static final String SAMPLE = "{ links : [ " + //
"{ rel : 'self', href : 'selfHref' }, " + //
@@ -40,39 +31,13 @@ public class DefaultLinkDiscovererUnitTest {
static final LinkDiscoverer discoverer = new DefaultLinkDiscoverer();
- @Test
- public void findsSingleLink() {
-
- assertThat(discoverer.findLinkWithRel("self", SAMPLE), is(new Link("selfHref")));
-
- List links = discoverer.findLinksWithRel("self", SAMPLE);
- assertThat(links, hasSize(1));
- assertThat(links, hasItem(new Link("selfHref")));
+ @Override
+ protected LinkDiscoverer getDiscoverer() {
+ return discoverer;
}
- @Test
- public void findsFirstLink() {
-
- assertThat(discoverer.findLinkWithRel("relation", SAMPLE), is(new Link("firstHref", "relation")));
- }
-
- @Test
- public void findsAllLinks() {
-
- List links = discoverer.findLinksWithRel("relation", SAMPLE);
- assertThat(links, hasSize(2));
- assertThat(links, hasItems(new Link("firstHref", "relation"), new Link("secondHref", "relation")));
- }
-
- @Test
- public void returnsForInexistingLink() {
- assertThat(discoverer.findLinkWithRel("something", SAMPLE), is(nullValue()));
- }
-
- @Test
- public void returnsForInxistingLinkFromInputStream() throws Exception {
-
- InputStream inputStream = new ByteArrayInputStream(SAMPLE.getBytes("UTF-8"));
- assertThat(discoverer.findLinkWithRel("something", inputStream), is(nullValue()));
+ @Override
+ protected String getInputString() {
+ return SAMPLE;
}
}
diff --git a/src/test/java/org/springframework/hateoas/hal/HalLinkDiscovererUnitTest.java b/src/test/java/org/springframework/hateoas/hal/HalLinkDiscovererUnitTest.java
new file mode 100644
index 00000000..2a1ea0ad
--- /dev/null
+++ b/src/test/java/org/springframework/hateoas/hal/HalLinkDiscovererUnitTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.hateoas.hal;
+
+import org.springframework.hateoas.LinkDiscoverer;
+import org.springframework.hateoas.core.AbstractLinkDiscovererUnitTests;
+
+/**
+ * Unit tests for {@link HalLinkDiscoverer}.
+ *
+ * @author Oliver Gierke
+ */
+public class HalLinkDiscovererUnitTest extends AbstractLinkDiscovererUnitTests {
+
+ static final LinkDiscoverer discoverer = new HalLinkDiscoverer();
+ static final String SAMPLE = "{ _links : { " + //
+ "self : { href : 'selfHref' }, " + //
+ "relation : [ " + //
+ "{ href : 'firstHref' }, { href : 'secondHref' }]}}";
+
+ @Override
+ protected LinkDiscoverer getDiscoverer() {
+ return discoverer;
+ }
+
+ @Override
+ protected String getInputString() {
+ return SAMPLE;
+ }
+}