eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'JSONPrinter':

Home

Documentation
www.exept.de
Everywhere
for:
[back]

Class: JSONPrinter


Inheritance:

   Object
   |
   +--Visitor
      |
      +--AspectVisitor
         |
         +--ObjectCoder
            |
            +--JSONPrinter

Package:
stx:goodies/communication
Category:
Net-Communication-JSON
Version:
rev: 1.60 date: 2023/09/05 09:01:12
user: stefan
file: JSONPrinter.st directory: goodies/communication
module: stx stc-classLibrary: communication

Description:


By default, I encode a limited subset of Smalltalk object types into a JSON representation.

Allowed are:
    strings,
    numbers
    booleans,
    nil,
    Arrays and OrderedCollections,
    Dictionaries,
    Date & Time (careful - see >> useISODateFormat)

Everything else is not representable. 
And I do not handle recursive data structures.

However:
    you can specify special type encodings which - with various detail and features
    allow more info to be generated as additional '@type' slots.
    Because similar schemes have been developed by various other frameworks,
    and no common standard exists, these may or may not fit your needs.
    If in doubt, you can add your own subclass of typeEncoder and do things customized.

    Provided:
        typeInfoFormat:   nil       - standard JSON only
        typeInfoFormat:   #stx      - (in lack of a better name):
                                      adds a slot named @type to dictionary objects
                                      Does NOT support references (i.e. shared objects)
        typeInfoFormat:   #stx2     - (also: in lack of a better name):
                                      wraps objects into a little dictionary containing
                                      @type and @value slots.
                                      Does NOT support references (i.e. shared objects)
        typeInfoFormat:   #stx3     - (a private scheme):
                                      wraps objects into a little dictionary containing
                                      @type and @value slots.
                                      In addition, stored objects get a @id slot,
                                      and can be references later with @ref
                                      However, it does NOT (currently) support recursive references
                                      from inner to outer object (i.e. from elements to their container),
                                      because inner objects are decoded first.
                                      This feature may be added in the future.


Notice:
    take a look at the other (alternative) JSON framework (Json),
    which can also be used to handle JSON data, and offers a more flexible
    object mapping mechanism to decode into real objects.
    
Author:
    Claus Gittinger
    Loosely Based upon Public Domain Code from Robin Redeker published in lists.gnu.org

copyright

COPYRIGHT (c) 2007 by eXept Software AG All Rights Reserved This software is furnished under a license and may be used only in accordance with the terms of that license and with the inclusion of the above copyright notice. This software may not be provided or otherwise made available to, or used by, any other person. No title to or ownership of the software is hereby transferred.

Class protocol:

API - encoding
o  encode: anObject
return a JSON string which represents the object (can be sent to JavaScript).

o  encode: anObject on: aStream
append a compact JSON string which represents the object onto aStream
(can be sent to JavaScript).

o  encode: anObject typeInfoFormat: formatSymbolOrNil on: aStream
append a compact JSON string which represents the object onto aStream
(can be sent to JavaScript).

o  encodePrettyPrinted: anObject
return a JSON string which represents the object (can be sent to JavaScript).

o  encodePrettyPrinted: anObject on: aStream
append a prettyPrinted (indented) JSON string which represents the object
onto aStream (can be sent to JavaScript).

o  encodePrettyPrinted: anObject printLimit: limitOrNil
return a JSON string which represents the object (can be sent to JavaScript).

o  encodePrettyPrinted: anObject printLimit: limitOrNil on: aStream
append a prettyPrinted (indented) JSON string which represents the object
onto aStream (can be sent to JavaScript).

o  encodePrettyPrinted: anObject printLimit: limitOrNil typeInfoFormat: formatSymbolOrNil on: aStream
append a prettyPrinted (indented) JSON string which represents the object
onto aStream (can be sent to JavaScript).

o  encodePrettyPrinted: anObject typeInfoFormat: formatSymbolOrNil on: aStream
append a prettyPrinted (indented) JSON string which represents the object
onto aStream (can be sent to JavaScript).

o  toJSON: anObject
return a JSON string which represents the object (can be sent to JavaScript).
Same as encode:
Added to make this encoder more protocol-conform to other encoders.

constants
o  defaultPrettyPrintLimit

o  deltaIndent

o  typeInfoFormatNone
if set via typeInfoFormat:, slots are encoded in standard JSON (no type info)

o  typeInfoFormatSTX
if set via typeInfoFormat:,
slots are encoded as:
{ '@type': , <classNameString> , 'value': <encoding> }

o  typeInfoFormatSTX2
if set via typeInfoFormat:,
object are store with an additional slot, as:
{ '@type': , <classNameString> ,
...
... regular slots ...
...
}

o  typeInfoFormatSTX3
if set via typeInfoFormat:,
object are stored wrapped, as:
{ '@obj': , <id>
'@type': <classNameString> ,
'@value':
...
... regular slots ...
...
}
references are resolved as:
{ '@ref': , <id> }

instance creation
o  new
return an initialized instance


Instance protocol:

accessing
o  dateFormat
aSymbolOrNil controls how dates/times/timestamps are encoded;
it can be:
#iso (the default), generates a string containing the ISO format
#expression, generates a non-standard (but supported by some browsers) format
which is an isntance creation expression (eg. 'new Date(y,m,d)').
#escapedSlashes, generates a format used/suggested by many users, which generates a
string with type info in escaped slashes.
(eg. '\/Date(<isoFormatDate>)\/').
a 1-arg block, responsible to generate whatever it wants

o  dateFormat: aSymbolOrNilOrBlock
aSymbolOrNil controls how dates/times/timestamps are encoded;
it can be:
#iso (the default), generates a string containing the ISO format
#expression, generates a non-standard (but supported by some browsers) format
which is an isntance creation expression (eg. 'new Date(y,m,d)').
#escapedSlashes, generates a format used/suggested by many users, which generates a
string with type info in escaped slashes.
(eg. '\/Date(<isoFormatDate>)\/').
a 1-arg block, responsible to generate whatever it wants

o  prettyPrint
returns true if pretty printing (i.e. with line breaks and indentation);
false if not (i.e. all in one long line)

o  prettyPrint: aBoolean
if false (the default), the generated JSON is compact;
if true, lines are indented to be more readable

Usage example(s):

     JSONPrinter new 
        encode:( Dictionary new
                    at:'hello' put:'world';
                    at:'foo' put:123;
                    at:'bar' put:(Dictionary new
                                    at:'one' put:1;
                                    at:'two' put:2;
                                    at:'three' put:#('aaa' 'bbb' 'ccc');
                                    yourself);
                    at:'baz' put:999.99;
                    yourself )
        on:Transcript.            

     JSONPrinter new 
        prettyPrint:true;
        encode:( Dictionary new
                    at:'hello' put:'world';
                    at:'foo' put:123;
                    at:'bar' put:(Dictionary new
                                    at:'one' put:1;
                                    at:'two' put:2;
                                    at:'three' put:#('aaa' 'bbb' 'ccc');
                                    yourself);
                    at:'baz' put:999.99;
                    yourself )
        on:Transcript.            

o  printLimit: numberOfChars
to set a limit on the generated output string.
Only to be used to present JSON to a user (as in the inspector);
Truncated JSON cannot be decoded (obviusly)

o  skipNil
if true, nil entries are skipped (default is false)

o  skipNil: aBoolean
if true, nil entries are skipped (default is false)

o  typeInfoFormat: formatSymbolOrNil
specify the format of the type info to be store with the slots.
For now, the formats supported are:
nil (default): no type info (standard JSON)
#stx : encode as { '@type': <classNameString> , 'value': {slots ...<encoding>} }
#stx2 : encode as { '@type': <classNameString> , slots... }
#stx3 : encode as { '@object': <id>, '@type': <classNameString> , { slots } }
more formats may be implemented in the future.

Usage example(s):

     JSONPrinter new 
        encode:{ Date today . Time now . Timestamp now }.

     JSONPrinter new 
        typeInfoFormat:(JSONPrinter typeInfoFormatSTX);
        encode:{ Date today . Time now . Timestamp now }. 

     JSONPrinter new 
        typeInfoFormat:(JSONPrinter typeInfoFormatSTX);
        encode:(10@10 corner:100@100). 

     JSONPrinter new 
        typeInfoFormat:(JSONPrinter typeInfoFormatSTX2);
        encode:{ Date today . Time now . Timestamp now }. 

     JSONPrinter new 
        typeInfoFormat:(JSONPrinter typeInfoFormatSTX2);
        encode:(10@10 corner:100@100). 

o  useISODateFormat
returns the date format generated.
If true (the default), a string containing the ISO format
is generated for Date, Time and Timestamp.
If false, a non-standard (but supported by some browsers) format
is generated (eg. 'new Date(y,m,d)')
It is not recommended to use this non-standard format, unless you really really need to.

Usage example(s):

JSONReader decode:(
         JSONPrinter new 
            encode:{ Date today . Time now . Timestamp now . 10 seconds }
     )    

     JSONPrinter new 
        useISODateFormat:false;
        encode:{ Date today . Time now . Timestamp now . 10 seconds }.  

o  useISODateFormat: aBoolean
if true (the default), a string containing the ISO format
is generated for Date, Time and Timestamp.
if false, a non-standard (but supported by some browsers) format
is generated (eg. 'new Date(y,m,d)').

Usage example(s):

     JSONPrinter new 
        encode:{ Date today . Time now . Timestamp now }.

     JSONPrinter new 
        useISODateFormat:false;
        encode:{ Date today . Time now . TimeStamp now }.

encoding / decoding
o  encode: anObject

o  encode: anObject on: aStream

initialization
o  initialize
(comment from inherited method)
just to ignore initialize to objects which do not need it

o  makeSlotEncoderFor: typeInfoFormat
JSONTypeEncoder newEncoderFor:nil
JSONTypeEncoder newEncoderFor:#stx

visiting
o  visitBoolean: aBoolean with: indent
callback from a boolean object to be encoded

o  visitCDatum: aCDatum with: indent
callback from a CDatums object to be encoded

o  visitDate: aDate with: indent
callback from a date object to be encoded

o  visitDictionary: aDictionary with: indent
callback from a dictionary object to be encoded

o  visitFloat: aFloat with: indent
callback from a float object to be encoded

o  visitInteger: anInteger with: indent
callback from an integer object to be encoded

o  visitNilWith: indent
callback from nil to be encoded

o  visitNumber: aNumber with: indent
callback from any other number (not floar or integer) to be encoded

o  visitObject: someObject with: indent
encode the object like a dictionary, using the object's instVarNames as keys.

o  visitProtoObject: someObject with: indent
callback from a proto/handle/proxy to be encoded

o  visitSequenceableCollection: aCollection with: indent
callback from a collection to be encoded

o  visitSet: aSet with: indent
callback from a set to be encoded

o  visitString: aString with: indent
callback from a string to be encoded

o  visitTime: aTime with: indent
callback from a time to be encoded

o  visitTimestamp: aTimestamp with: indent
callback from a timestamp to be encoded


Examples:


see examples in JSONReader


ST/X 7.7.0.0; WebServer 1.702 at 20f6060372b9.unknown:8081; Fri, 03 May 2024 01:07:15 GMT