PropertyList implements Iterable<PropertySpec>, Serializable, PortableObject { public static PropertyList fromString(String sPropertyList) { PropertyList properties = new PropertyList(); sPropertyList = sPropertyList.trim(); StringBuilder name = new StringBuilder(); PropertyList list = null; int pos = 0; while (pos < sPropertyList.length()) { char c = sPropertyList.charAt(pos++); if (c == ',') { properties.add(new PropertySpec(name.toString(), list)); name = new StringBuilder(); list = null; } else if (c == ':') { pos++; int parenCount = 1; StringBuilder innerList = new StringBuilder(); while (parenCount > 0 && pos < sPropertyList.length()) { char s = sPropertyList.charAt(pos++); if (s == ')') { parenCount--; } else if (s == '(') { parenCount++; } if (parenCount > 0) { innerList.append(s); } } list = fromString(innerList.toString()); } else if (c != ' ') { name.append(c); } } if (name.length() > 0) { properties.add(new PropertySpec(name.toString(), list)); } return properties; } PropertyList();  PropertyList(PropertySpec... properties);  PropertyList(List<PropertySpec> properties); static PropertyList fromString(String sPropertyList); void add(PropertySpec property); @Override Iterator<PropertySpec> iterator(); @Override void readExternal(PofReader reader); @Override void writeExternal(PofWriter writer);  }
@Test public void testFromString() { PropertyList pl = PropertyList.fromString("name,address:(city,state),orders:(date,lineItems:(sku,price),amount)"); List<PropertySpec> l = pl.getProperties(); assertEquals(3, l.size()); assertEquals("name", l.get(0).getName()); assertNull(l.get(0).getPropertyList()); assertEquals("address", l.get(1).getName()); assertNotNull(l.get(1).getPropertyList()); assertEquals("orders", l.get(2).getName()); assertNotNull(l.get(2).getPropertyList()); PropertySpec lineItems = l.get(2).getPropertyList().getProperties().get(1); assertEquals("lineItems", lineItems.getName()); assertNotNull(lineItems.getPropertyList()); }