/*
 * Created on 21 Feb 2008
 */
package uk.org.ponder.json.support;

import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;

import uk.org.ponder.conversion.GeneralLeafParser;
import uk.org.ponder.iterationutil.EnumerationConverter;
import uk.org.ponder.json.JSONWriter;
import uk.org.ponder.saxalizer.SAXalizerMappingContext;
import uk.org.ponder.saxalizer.support.MethodAnalyser;
import uk.org.ponder.saxalizer.support.SAXAccessMethod;
import uk.org.ponder.streamutil.write.PrintOutputStream;

/** Convert any recognizable object tree into a textual JSON representation **/

public class EnJSONalizer {
  private JSONWriter writer;
  private GeneralLeafParser leafParser = new GeneralLeafParser();
  private SAXalizerMappingContext mappingContext;
  
  public EnJSONalizer(SAXalizerMappingContext smc, OutputStream os) {
    this.mappingContext = smc;
    this.writer = new JSONWriter(os);
  }
  
  public EnJSONalizer(SAXalizerMappingContext smc, PrintOutputStream pos) {
    this.mappingContext = smc;
    this.writer = new JSONWriter(pos);
  }
  
  public void writeObject(Object towrite) {
    if (towrite == null) {
      writer.write(null);
      return;
    }
    Class clazz = towrite.getClass();
    if (leafParser.isLeafType(clazz)) {
      boolean quote = !(towrite instanceof Number);
      if (quote) writer.writeRaw("\"");
      writer.write(leafParser.render(towrite));
      if (quote) writer.writeRaw("\"");
    }
    else if (EnumerationConverter.isEnumerable(clazz) && !EnumerationConverter.isMappable(clazz)) {
      Enumeration enumm = EnumerationConverter.getEnumeration(towrite);
      writer.writeRaw("[");
      boolean first = true;
      while (enumm.hasMoreElements()) {
        Object obj = enumm.nextElement();
        if (!first) {
          writer.writeRaw(", ");
        }
        first = false;
        writeObject(obj);
      }
      writer.writeRaw("]");
    }
    else {
      writer.writeRaw("{");
      boolean first = true;
      if (towrite instanceof Map) {
        Map map = (Map) towrite;
        for (Iterator it = map.keySet().iterator(); it.hasNext();) {
          Object key = it.next();
          if (!first) {
            writer.writeRaw(", ");
          }
          first = false;
          writeObject(leafParser.render(key));
          writer.writeRaw(": ");
          writeObject(map.get(key));
        }
      }
      MethodAnalyser ma = mappingContext.getAnalyser(clazz);
      for (int i = 0; i < ma.allgetters.length; ++ i) {
        SAXAccessMethod sam = ma.allgetters[i];
        if (!first) {
          writer.writeRaw(", ");
        }
        first = false;
        writeObject(sam.getPropertyName());
        writer.writeRaw(": ");
        writeObject(sam.getChildObject(towrite));
      }
      writer.writeRaw("}");
    }
  }
}

@@ -638,16 +638,17 @@
 tation *
+ 
 */%0D%0A%0D%0Apu
@@ -822,18 +822,16 @@
 ntext;%0D%0A
-  
 %0D%0A  publ
@@ -963,34 +963,32 @@
 iter(os);%0D%0A  %7D%0D%0A
-  
 %0D%0A  public EnJSO
@@ -1127,18 +1127,16 @@
 ;%0D%0A  %7D%0D%0A
-  
 %0D%0A  publ
@@ -1392,32 +1392,41 @@
       if (quote)
+%0D%0A       
  writer.writeRaw
@@ -1499,16 +1499,25 @@
  (quote)
+%0D%0A       
  writer.
@@ -1593,16 +1593,25 @@
 e(clazz)
+%0D%0A       
  && !Enu
@@ -2511,24 +2511,40 @@
 %7D%0D%0A      %7D%0D%0A
+      else %7B%0D%0A  
       Method
@@ -2589,24 +2589,26 @@
 er(clazz);%0D%0A
+  
       for (i
@@ -2649,15 +2649,16 @@
 ; ++
- 
 i) %7B%0D%0A
+  
     
@@ -2702,16 +2702,18 @@
 rs%5Bi%5D;%0D%0A
+  
         
@@ -2729,32 +2729,34 @@
 t) %7B%0D%0A          
+  
 writer.writeRaw(
@@ -2763,35 +2763,39 @@
 %22, %22);%0D%0A        
+  
 %7D%0D%0A
+  
         first = 
@@ -2802,32 +2802,34 @@
 false;%0D%0A        
+  
 writeObject(sam.
@@ -2849,32 +2849,34 @@
 me());%0D%0A        
+  
 writer.writeRaw(
@@ -2875,32 +2875,34 @@
 riteRaw(%22: %22);%0D%0A
+  
         writeObj
@@ -2932,24 +2932,35 @@
 towrite));%0D%0A
+        %7D%0D%0A
       %7D%0D%0A   

Fix EnJSONalizer to not report "empty" property for Maps