com.quinsoft.zeidon.utils.WriteOisToJsonStreamNoIncrementals Maven / Gradle / Ivy
The newest version!
/**
This file is part of the Zeidon Java Object Engine (Zeidon JOE).
Zeidon JOE is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Zeidon JOE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Zeidon JOE. If not, see .
Copyright 2009-2015 QuinSoft
*/
package com.quinsoft.zeidon.utils;
import java.io.Writer;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.EnumSet;
import org.apache.commons.lang3.StringUtils;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.quinsoft.zeidon.AttributeInstance;
import com.quinsoft.zeidon.EntityInstance;
import com.quinsoft.zeidon.SerializationMapping;
import com.quinsoft.zeidon.SerializeOi;
import com.quinsoft.zeidon.StreamWriter;
import com.quinsoft.zeidon.View;
import com.quinsoft.zeidon.WriteOiFlags;
import com.quinsoft.zeidon.ZeidonException;
import com.quinsoft.zeidon.domains.BigDecimalDomain;
import com.quinsoft.zeidon.domains.BooleanDomain;
import com.quinsoft.zeidon.domains.Domain;
import com.quinsoft.zeidon.domains.DoubleDomain;
import com.quinsoft.zeidon.domains.IntegerDomain;
import com.quinsoft.zeidon.domains.LongDomain;
import com.quinsoft.zeidon.objectdefinition.AttributeDef;
import com.quinsoft.zeidon.objectdefinition.EntityDef;
/**
* Serializes an OI by writing it as a JSON stream. This does not write any Zeidon
* information (e.g. incremental flags). Zeidon can retrieve an OI written with this
* object but it won't have any linking or incremental flags.
*
* @author dgc
*
*/
public class WriteOisToJsonStreamNoIncrementals implements StreamWriter
{
private final static String VERSION = "1";
private Collection extends View> viewList;
private EnumSet flags;
private SerializeOi options;
private JsonGenerator jg;
private SerializationMapping mapper;
@Override
public void writeToStream( SerializeOi options, Writer writer )
{
this.viewList = options.getViewList();
if ( options.getFlags() == null )
flags = EnumSet.noneOf( WriteOiFlags.class );
else
flags = options.getFlags();
if ( flags.contains( WriteOiFlags.INCREMENTAL ) )
throw new ZeidonException( "This JSON stream writer not intended for writing incremental." );
this.options = options;
mapper = options.getSerializationMapping();
JsonFactory jsonF = new JsonFactory();
try
{
jg = jsonF.createGenerator( writer );
if ( ! options.isCompressed() )
jg.useDefaultPrettyPrinter();
jg.writeStartObject();
// jg.writeStringField( "version", VERSION );
for ( View view : viewList )
writeOi( view );
jg.writeEndObject();
jg.close();
}
catch ( Exception e )
{
throw ZeidonException.wrapException( e );
}
}
private void writeOi( View view ) throws Exception
{
view = view.newView(); // To preserve cursor positions in the original view.
view.setInternal( true ); // So it doesn't show up in the browser.
Integer rootCount = view.getTotalRootCount();
if ( rootCount != null )
jg.writeNumberField( "totalRootCount", rootCount );
EntityDef rootEntityDef = view.getLodDef().getRoot();
jg.writeArrayFieldStart( objectName( rootEntityDef ) );
if ( ! view.isEmpty() )
{
jg.writeStartObject();
for ( EntityInstance ei: view.cursor( rootEntityDef ).eachEntity() )
{
if ( ei.hasPrevTwin() )
jg.writeStartObject();
writeEntity( ei );
if ( ei.hasNextTwin() )
jg.writeEndObject();
}
jg.writeEndObject();
}
jg.writeEndArray();
}
/**
* Convert the name of the EntityDef to the object name used in JSON.
* @param entityDef
* @return
*/
private String objectName( EntityDef entityDef )
{
String objectName = mapper.entityToRecord( entityDef );
return camelCaseName( objectName );
}
private String fieldName( AttributeDef attributeDef )
{
String fieldName = mapper.attributeToField( attributeDef );
return camelCaseName( fieldName );
}
private String camelCaseName( String name )
{
if ( ! options.isCamelCase() )
return name;
char[] nameChars = name.toCharArray();
for ( int i = 0; i < nameChars.length; i++ )
{
if ( ! Character.isUpperCase( nameChars[ i ] ) )
break;
nameChars[ i ] = Character.toLowerCase( nameChars[ i ] );
}
return String.valueOf( nameChars );
}
private EntityDef writeEntity( EntityInstance ei ) throws Exception
{
try
{
// See if we need to open or close an array field.
final EntityDef entityDef = ei.getEntityDef();
for ( AttributeDef attributeDef : entityDef.getAttributes() )
{
if ( attributeDef.isHidden() && ! options.isWriteHiddenAttributes() )
continue;
if ( attributeDef.isDerived() )
continue;
AttributeInstance attrib = ei.getAttribute( attributeDef );
if ( attrib.isNull() )
continue;
Domain domain = attributeDef.getDomain();
String jsonName = fieldName( attributeDef );
if ( domain instanceof IntegerDomain )
jg.writeNumberField( jsonName, attrib.getInteger() );
else
if ( domain instanceof DoubleDomain )
jg.writeNumberField( jsonName, attrib.getDouble() );
else
if ( domain instanceof BooleanDomain )
jg.writeBooleanField( jsonName, attrib.getBoolean() );
else
if ( domain instanceof LongDomain )
jg.writeNumberField( jsonName, (Long) attrib.getValue() );
else
if ( domain instanceof BigDecimalDomain )
jg.writeNumberField( jsonName, (BigDecimal) attrib.getValue() );
else
{
String value = attrib.getString( null );
// getAttributes will include null attributes if they have been updated
// (i.e. explicitly set to null). Since we aren't writing incrementals
// we don't want those so check for null.
if ( ! StringUtils.isBlank( value ) )
jg.writeStringField( fieldName( attrib.getAttributeDef() ), value );
}
}
// Loop through the children and add them.
for ( EntityInstance child : ei.getDirectChildren( false, false ) )
{
EntityDef childEntityDef = child.getEntityDef();
if ( ! child.hasPrevTwin() )
{
if ( childEntityDef.getMaxCardinality() > 1 )
{
jg.writeArrayFieldStart( objectName( childEntityDef ) );
jg.writeStartObject();
}
else
jg.writeObjectFieldStart( objectName( childEntityDef ) );
}
else
jg.writeStartObject();
writeEntity( child );
jg.writeEndObject();
if ( ! child.hasNextTwin() )
{
if ( childEntityDef.getMaxCardinality() > 1 )
jg.writeEndArray();
}
}
return entityDef;
}
catch ( Exception e )
{
throw ZeidonException.wrapException( e ).prependEntityInstance( ei );
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy