Introduce constructor for compact object notation
diff --git a/src/main/java/org/yaml/snakeyaml/extensions/compactnotation/CompactConstructor.java b/src/main/java/org/yaml/snakeyaml/extensions/compactnotation/CompactConstructor.java
new file mode 100644
index 0000000..9f0e269
--- /dev/null
+++ b/src/main/java/org/yaml/snakeyaml/extensions/compactnotation/CompactConstructor.java
@@ -0,0 +1,115 @@
+/**
+ * Copyright (c) 2008-2010, http://code.google.com/p/snakeyaml/
+ *
+ * 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.yaml.snakeyaml.extensions.compactnotation;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.yaml.snakeyaml.constructor.Constructor;
+import org.yaml.snakeyaml.nodes.ScalarNode;
+
+/**
+ * Construct a custom Java instance out of a compact format.
+ */
+public class CompactConstructor extends Constructor {
+ private static final Pattern FIRST_PATTERN = Pattern
+ .compile("(\\p{Alpha}\\w*)(\\s*)\\((.*?)\\)");
+ private static final Pattern PROPERTY_NAME_PATTERN = Pattern
+ .compile("\\s*(\\p{Alpha}\\w*)\\s*=(.+)");
+
+ @Override
+ protected Object constructScalar(ScalarNode node) {
+ CompactData data = getCompactData(node.getValue());
+ if (data != null) {
+ return constructCompactFormat(node, data);
+ } else {
+ return super.constructScalar(node);
+ }
+ }
+
+ protected Object constructCompactFormat(ScalarNode node, CompactData data) {
+ System.out.println("TODO: " + data);
+ return super.constructScalar(node);
+ }
+
+ public CompactData getCompactData(String scalar) {
+ if (!scalar.endsWith(")")) {
+ return null;
+ }
+ if (scalar.indexOf('=') < 0 || scalar.indexOf('(') < 0) {
+ return null;
+ }
+ Matcher m = FIRST_PATTERN.matcher(scalar);
+ if (m.matches()) {
+ String tag = m.group(1);
+ String content = m.group(3);
+ String[] names = content.split("\\s*,\\s*");
+ if (names.length == 0) {
+ return null;
+ }
+ CompactData data = new CompactData(tag);
+ for (int i = 0; i < names.length; i++) {
+ String section = names[i];
+ Matcher sm = PROPERTY_NAME_PATTERN.matcher(section);
+ if (sm.matches()) {
+ String name = sm.group(1);
+ String value = sm.group(2).trim();
+ if ("".equals(value)) {
+ return null;
+ }
+ data.getProperties().put(name, value);
+ } else {
+ return null;
+ }
+ }
+ return data;
+ }
+ return null;
+ }
+
+ class CompactData {
+ private String prefix;
+ private Map<String, String> properties = new HashMap<String, String>();
+
+ public CompactData(String prefix) {
+ this.prefix = prefix;
+ }
+
+ public String getPrefix() {
+ return prefix;
+ }
+
+ public void setPrefix(String prefix) {
+ this.prefix = prefix;
+ }
+
+ public Map<String, String> getProperties() {
+ return properties;
+ }
+
+ public void setProperties(Map<String, String> properties) {
+ this.properties = properties;
+ }
+
+ @Override
+ public String toString() {
+ return "CompactData: " + prefix + " " + properties;
+ }
+ }
+}
diff --git a/src/test/java/org/yaml/snakeyaml/extensions/compactnotation/CompactConstructorExampleTest.java b/src/test/java/org/yaml/snakeyaml/extensions/compactnotation/CompactConstructorExampleTest.java
new file mode 100644
index 0000000..1653429
--- /dev/null
+++ b/src/test/java/org/yaml/snakeyaml/extensions/compactnotation/CompactConstructorExampleTest.java
@@ -0,0 +1,34 @@
+/**
+ * Copyright (c) 2008-2010, http://code.google.com/p/snakeyaml/
+ *
+ * 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.yaml.snakeyaml.extensions.compactnotation;
+
+import junit.framework.TestCase;
+
+import org.yaml.snakeyaml.Util;
+import org.yaml.snakeyaml.Yaml;
+
+public class CompactConstructorExampleTest extends TestCase {
+
+ public void test1() {
+ CompactConstructor flow = new CompactConstructor();
+ Yaml yaml = new Yaml(flow);
+ String doc = Util.getLocalResource("compactnotation/container1.yaml");
+ Object obj = yaml.load(doc);
+ assertNotNull(obj);
+ }
+
+}
diff --git a/src/test/java/org/yaml/snakeyaml/extensions/compactnotation/CompactConstructorTest.java b/src/test/java/org/yaml/snakeyaml/extensions/compactnotation/CompactConstructorTest.java
new file mode 100644
index 0000000..2e3301e
--- /dev/null
+++ b/src/test/java/org/yaml/snakeyaml/extensions/compactnotation/CompactConstructorTest.java
@@ -0,0 +1,73 @@
+/**
+ * Copyright (c) 2008-2010, http://code.google.com/p/snakeyaml/
+ *
+ * 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.yaml.snakeyaml.extensions.compactnotation;
+
+import junit.framework.TestCase;
+
+import org.yaml.snakeyaml.extensions.compactnotation.CompactConstructor.CompactData;
+
+public class CompactConstructorTest extends TestCase {
+
+ public void testNoCompactData() {
+ CompactConstructor flow = new CompactConstructor();
+ assertNull(flow.getCompactData("JFrame()"));
+ assertNull(flow.getCompactData("scalar"));
+ assertNull(flow.getCompactData("123"));
+ assertNull(flow.getCompactData("(name=frame,title=My Frame)"));
+ assertNull(flow.getCompactData("JFrame name=frame,title=My Frame)"));
+ assertNull(flow.getCompactData("JFrame name=frame,title=My Frame"));
+ assertNull(flow.getCompactData("JFrame(name=frame,title=My Frame"));
+ assertNull(flow.getCompactData("JFrame(name=frame,title=My Frame)b"));
+ assertNull(flow.getCompactData("JFrame(name=frame,title=My Frame) "));
+ assertNull(flow.getCompactData("JFrame(name=)"));
+ assertNull(flow.getCompactData("JFrame(=name)"));
+ assertNull(flow.getCompactData("JFrame(name)"));
+ }
+
+ public void testGetCompactData1() {
+ CompactConstructor flow = new CompactConstructor();
+ CompactData data = flow.getCompactData("JFrame(name=frame)");
+ assertNotNull(data);
+ assertEquals("JFrame", data.getPrefix());
+ assertEquals(1, data.getProperties().size());
+ assertEquals("frame", data.getProperties().get("name"));
+ }
+
+ public void testGetCompactData2() {
+ CompactConstructor flow = new CompactConstructor();
+ CompactData data = flow.getCompactData("Frame(name=frame,title=My Frame)");
+ assertNotNull(data);
+ assertEquals("Frame", data.getPrefix());
+ assertEquals(2, data.getProperties().size());
+ assertEquals("frame", data.getProperties().get("name"));
+ assertEquals("My Frame", data.getProperties().get("title"));
+
+ assertNotNull(flow.getCompactData("JFrame ( name = frame , title = My Frame )"));
+ }
+
+ public void testGetCompactData3() {
+ CompactConstructor flow = new CompactConstructor();
+ CompactData data = flow
+ .getCompactData("JFrame ( name = frame , title = My Frame, number= 123 )");
+ assertNotNull(data);
+ assertEquals("JFrame", data.getPrefix());
+ assertEquals(3, data.getProperties().size());
+ assertEquals("frame", data.getProperties().get("name"));
+ assertEquals("My Frame", data.getProperties().get("title"));
+ assertEquals("123", data.getProperties().get("number"));
+ }
+}
diff --git a/src/test/resources/compactnotation/container1.yaml b/src/test/resources/compactnotation/container1.yaml
new file mode 100644
index 0000000..398fd80
--- /dev/null
+++ b/src/test/resources/compactnotation/container1.yaml
@@ -0,0 +1,4 @@
+Container(name=parent, id=123):
+ components:
+ - Component(name=open, id=111)
+ - Component(name=close, id=222)