/* * � Copyright IBM Corp. 2010, 2014 * * 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 com.ibm.domino.services.util; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Collection; import lotus.domino.DateTime; import lotus.domino.NotesException; import com.ibm.commons.util.AbstractIOException; import com.ibm.commons.util.io.json.JsonException; import com.ibm.commons.util.io.json.JsonGenerator; import com.ibm.domino.services.rest.RestServiceConstants; /** * Specialized JSON writer within a StringBuilder. * * @author Philippe Riand */ public class JsonBuilder extends JsonGenerator.StringBuilderGenerator { private int objectLevels = 0; private boolean first[] = new boolean[32]; // max 32 for now... public JsonBuilder(StringBuilder b, boolean compact) { super(null,b,compact); } public void startObject() throws IOException { nl(); indent(); out('{'); first[++objectLevels]=true; incIndent(); } public void endObject() throws IOException { nl(); decIndent(); indent(); out('}'); first[--objectLevels]=false; } public void startArray() throws IOException { nl(); indent(); out('['); first[++objectLevels]=true; incIndent(); } public void endArray() throws IOException { nl(); decIndent(); indent(); out(']'); first[--objectLevels]=false; } public void startArrayItem() throws IOException { if(!first[objectLevels]) { out(','); } } public void endArrayItem() throws IOException { first[objectLevels]=false; } public void startProperty(String propertyName) throws IOException { if(!first[objectLevels]) { out(','); } else { first[objectLevels]=false; } nl(); incIndent(); indent(); outPropertyName(propertyName); out(':'); } public void endProperty() throws IOException { decIndent(); } // Should be moved to the core libs @Override public void outNumberLiteral(double d) throws IOException { long l = (long)d; if((double)l==d) { String s = Long.toString(l); out(s); } else { String s = Double.toString(d); out(s); } } // Should be moved to the core libs public void outDateLiteral(Date value) throws IOException { String s = dateToString(value); outStringLiteral(s); } public void outDateLiteral(DateTime value) throws IOException { String s = dateToString(value); out(s); } public void outDominoValue(Object value) throws IOException { try { if(value==null) { outNull(); return; } if(value instanceof String) { outStringLiteral((String)value); return; } if(value instanceof Number) { outNumberLiteral(((Number)value).doubleValue()); return; } if(value instanceof Boolean) { outBooleanLiteral(((Boolean)value).booleanValue()); return; } if(value instanceof Date) { outStringLiteral(dateToString((Date)value)); return; } if(value instanceof DateTime) { try { outStringLiteral(dateToString(((DateTime)value).toJavaDate())); return; } catch(NotesException ex) { throw new AbstractIOException(ex,""); } } if (value instanceof Collection) { startArray(); Collection v = (Collection) value; for (Object raw : v) { startArrayItem(); outDominoValue(raw); endArrayItem(); } endArray(); return; } // Should not happen... outStringLiteral("???"); } catch(JsonException ex) { throw new AbstractIOException(ex,""); } } //TODO: What the TZ should be?? private static SimpleDateFormat ISO8601 = new SimpleDateFormat(RestServiceConstants.TIME_FORMAT_B); //$NON-NLS-1$ public String dateToString(Date value) throws IOException { return ISO8601.format(value); } public String dateToString(DateTime value) throws IOException { try { return ISO8601.format(value.toJavaDate()); } catch(NotesException ex) { throw new AbstractIOException(ex,""); } } public Date toJavaDate(DateTime value) throws IOException { try { return value.toJavaDate(); } catch(NotesException ex) { throw new AbstractIOException(ex,""); } } }