/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

package foam.core;

import foam.dao.pg.IndexedPreparedStatement;
import foam.nanos.logger.Logger;
import java.lang.UnsupportedOperationException;
import java.util.ArrayList;
import java.util.List;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public abstract class AbstractArrayPropertyInfo
  extends AbstractPropertyInfo
{
  @Override
  public void setFromString(Object obj, String value) {
    if ( value == null ) {
      this.set(obj, null);
      return;
   } 
   String[] s  = value.split(",", -1);
   this.set(obj, s);
  }

  public abstract String of();

  // NESTED ARRAY
  @Override
  public Object fromXML(X x, XMLStreamReader reader) {
    List objList = new ArrayList();
    String startTag = reader.getLocalName();
    try {
      int eventType;
      while ( reader.hasNext() ) {
        eventType = reader.next();
        switch ( eventType ) {
          case XMLStreamConstants.START_ELEMENT:
            if ( reader.getLocalName().equals("value") ) {
              // TODO: TYPE CASTING FOR PROPER CONVERSION. NEED FURTHER SUPPORT FOR PRIMITIVE TYPES
              throw new UnsupportedOperationException("Primitive typed array XML reading is not supported yet");
            }
            break;
          case XMLStreamConstants.END_ELEMENT:
            if ( reader.getLocalName() == startTag ) { return objList.toArray(); }
        }
      }
    } catch (XMLStreamException ex) {
      Logger logger = (Logger) x.get("logger");
      logger.error("Premature end of XML file");
    }
    return objList.toArray();
  }

  @Override
  public void toXML (FObject obj, Document doc, Element objElement) {
    if ( this.f(obj) == null ) return;

    Element prop = doc.createElement(this.getName());
    objElement.appendChild(prop);

    Object[] nestObj = (Object[]) this.f(obj);
    for ( int k = 0; k < nestObj.length; k++ ) {
      Element nestedProp = doc.createElement("value");
      nestedProp.appendChild(doc.createTextNode(nestObj[k].toString()));
      prop.appendChild(nestedProp);
    }
  }

  @Override
  public void setStatementValue(IndexedPreparedStatement stmt, FObject o) throws java.sql.SQLException {
    Object obj = this.get(o);
    if ( obj == null ) {
      stmt.setObject(null);
      return;
    }
    Object[] os = (Object[]) obj;
    java.lang.StringBuilder sb = new java.lang.StringBuilder();
    int length = os.length;
    if ( length == 0 ) {
      stmt.setObject(null);
      return;
    }
    for ( int i = 0 ; i < length ; i++ ) {
      if ( os[i] == null )
        sb.append("");
      else
        sb.append(os[i]);
      if ( i < length - 1 ) {
        sb.append(",");
      }
    }
    stmt.setObject(sb.toString());
  }

  @Override
  public void setFromResultSet(java.sql.ResultSet resultSet, int index, FObject o) throws java.sql.SQLException{
    String value = (String) resultSet.getObject(index);
    setFromString(o, value);
  }
}

@@ -646,24 +646,75 @@
 ng value) %7B%0A
+    System.out.println(%22return String: %22 + value);%0A
     if ( val
@@ -777,67 +777,1007 @@
    %7D
- %0A   String
+%0A   java.util.List%3CString%3E list = new java.util.LinkedList%3CString%3E();%0A   StringBuilder sb = new StringBuilder(); %0A   char prev = '$';%0A   int length = value.length();%0A   char
 %5B%5D 
+c
 s 
- = value.split(%22,%22, -1);%0A   this.set(obj, s
+= value.toCharArray();%0A   for ( int i = 0 ; i %3C cs.length ; i++ ) %7B%0A       if ( cs%5Bi%5D == '%5C%5C' ) %7B%0A           if ( prev == '%5C%5C' ) %7B%0A               sb.append(%22%5C%5C%22);%0A               prev = '$';%0A           %7D else %7B%0A               prev = '%5C%5C';%0A           %7D%0A       %7D else if ( cs%5Bi%5D == ',' ) %7B%0A           if ( prev == '%5C%5C' ) %7B%0A               sb.append(',');%0A           %7D else %7B%0A               list.add(sb.toString());%0A               sb.setLength(0);%0A           %7D%0A           prev = '$';%0A       %7D else %7B%0A           sb.append(cs%5Bi%5D);%0A           prev = cs%5Bi%5D;%0A       %7D%0A   %7D%0A   list.add(sb.toString());%0A   int resultSize = list.size();%0A   System.out.println(%22list size: %22 + list.size());%0A   String%5B%5D result = new String%5BresultSize%5D;%0A   //add support for other array types%0A   this.set(obj, list.subList(0, resultSize).toArray(result)
 );%0A 
@@ -3792,16 +3792,18 @@
     else
+ %7B
 %0A       
@@ -3814,27 +3814,88 @@
 append(os%5Bi%5D
-);%0A
+.toString().replace(%22%5C%5C%22,%22%5C%5C%5C%5C%22).replace(%22,%22,%22%5C%5C,%22));%0A      %7D%0A  
       if ( i

modify setFromString()