001/*
002 * Copyright (c) 2004-2020, Oracle and/or its affiliates.
003 *
004 * Licensed under the 2-clause BSD license.
005 *
006 * Redistribution and use in source and binary forms, with or without
007 * modification, are permitted provided that the following conditions are met:
008 *
009 * 1. Redistributions of source code must retain the above copyright notice,
010 *    this list of conditions and the following disclaimer.
011 *
012 * 2. Redistributions in binary form must reproduce the above copyright notice,
013 *    this list of conditions and the following disclaimer in the documentation
014 *    and/or other materials provided with the distribution.
015 *
016 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
017 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
018 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
019 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
020 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
021 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
022 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
023 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
024 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
025 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
026 * POSSIBILITY OF SUCH DAMAGE.
027 */
028
029package com.oracle.labs.mlrg.olcut.config.json;
030
031import com.fasterxml.jackson.core.JsonGenerator;
032import com.oracle.labs.mlrg.olcut.config.io.ConfigLoader;
033import com.oracle.labs.mlrg.olcut.config.io.ConfigWriter;
034import com.oracle.labs.mlrg.olcut.config.io.ConfigWriterException;
035import com.oracle.labs.mlrg.olcut.config.property.ListProperty;
036import com.oracle.labs.mlrg.olcut.config.property.MapProperty;
037import com.oracle.labs.mlrg.olcut.config.property.Property;
038import com.oracle.labs.mlrg.olcut.config.SerializedObject;
039import com.oracle.labs.mlrg.olcut.config.property.SimpleProperty;
040
041import java.io.IOException;
042import java.util.Map;
043import java.util.Map.Entry;
044
045/**
046 *
047 */
048public class JsonConfigWriter implements ConfigWriter {
049
050    private final JsonGenerator writer;
051
052    public JsonConfigWriter(JsonGenerator writer) {
053        this.writer = writer;
054    }
055
056    @Override
057    public void writeStartDocument() throws ConfigWriterException {
058        try {
059            writer.writeStartObject();
060            writer.writeObjectFieldStart(ConfigLoader.CONFIG);
061        } catch (IOException e) {
062            throw new ConfigWriterException(e);
063        }
064    }
065
066    @Override
067    public void writeEndDocument() throws ConfigWriterException {
068        try {
069            writer.writeEndObject();
070            writer.writeEndObject();
071        } catch (IOException e) {
072            throw new ConfigWriterException(e);
073        }
074    }
075
076    @Override
077    public void writeGlobalProperties(Map<String, String> props) throws ConfigWriterException {
078        try {
079            if (!props.isEmpty()) {
080                writer.writeObjectFieldStart(ConfigLoader.GLOBALPROPERTIES);
081                for (Entry<String, String> e : props.entrySet()) {
082                    writer.writeStringField(e.getKey(), e.getValue());
083                }
084                writer.writeEndObject();
085            }
086        } catch (IOException e) {
087            throw new ConfigWriterException(e);
088        }
089    }
090
091    @Override
092    public void writeSerializedObjects(Map<String, SerializedObject> map) throws ConfigWriterException {
093        try {
094            if (!map.isEmpty()) {
095                writer.writeArrayFieldStart(ConfigLoader.SERIALIZEDOBJECTS);
096                for (Entry<String, SerializedObject> e : map.entrySet()) {
097                    writer.writeStartObject();
098                    writer.writeStringField(ConfigLoader.NAME, e.getValue().getName());
099                    writer.writeStringField(ConfigLoader.TYPE, e.getValue().getClassName());
100                    writer.writeStringField(ConfigLoader.LOCATION, e.getValue().getLocation());
101                    writer.writeEndObject();
102                }
103                writer.writeEndArray();
104            }
105        } catch (IOException e) {
106            throw new ConfigWriterException(e);
107        }
108    }
109
110    @Override
111    public void writeStartComponents() throws ConfigWriterException {
112        try {
113            writer.writeArrayFieldStart(ConfigLoader.COMPONENTS);
114        } catch (IOException e) {
115            throw new ConfigWriterException(e);
116        }
117    }
118
119    @Override
120    public void writeComponent(Map<String, String> attributes, Map<String, Property> properties) {
121        try {
122            writer.writeStartObject();
123            writer.writeStringField(ConfigLoader.NAME, attributes.get(ConfigLoader.NAME));
124            writer.writeStringField(ConfigLoader.TYPE, attributes.get(ConfigLoader.TYPE));
125            writer.writeStringField(ConfigLoader.EXPORT, attributes.get(ConfigLoader.EXPORT));
126            writer.writeStringField(ConfigLoader.IMPORT, attributes.get(ConfigLoader.IMPORT));
127            if (attributes.containsKey(ConfigLoader.ENTRIES)) {
128                writer.writeStringField(ConfigLoader.ENTRIES, attributes.get(ConfigLoader.ENTRIES));
129            }
130            if (attributes.containsKey(ConfigLoader.LEASETIME)) {
131                writer.writeStringField(ConfigLoader.LEASETIME, attributes.get(ConfigLoader.LEASETIME));
132            }
133            if (attributes.containsKey(ConfigLoader.SERIALIZED)) {
134                writer.writeStringField(ConfigLoader.SERIALIZED, attributes.get(ConfigLoader.SERIALIZED));
135            }
136
137            if (!properties.isEmpty()) {
138                writer.writeObjectFieldStart(ConfigLoader.PROPERTIES);
139                for (Entry<String, Property> property : properties.entrySet()) {
140                    String key = property.getKey();
141                    Property value = property.getValue();
142                    if (value instanceof ListProperty) {
143                        //
144                        // Must be a string or component list
145                        writer.writeArrayFieldStart(key);
146                        for (SimpleProperty s : ((ListProperty) value).getSimpleList()) {
147                            writer.writeStartObject();
148                            writer.writeStringField(ConfigLoader.ITEM,s.getValue());
149                            writer.writeEndObject();
150                        }
151                        for (Class<?> c : ((ListProperty) value).getClassList()) {
152                            writer.writeStartObject();
153                            writer.writeStringField(ConfigLoader.TYPE,c.getName());
154                            writer.writeEndObject();
155                        }
156                        writer.writeEndArray();
157                    } else if (value instanceof MapProperty) {
158                        //
159                        // Must be a string,string map
160                        writer.writeObjectFieldStart(key);
161                        for (Map.Entry<String, SimpleProperty> e : ((MapProperty) value).getMap().entrySet()) {
162                            writer.writeStringField(e.getKey(),e.getValue().getValue());
163                        }
164                        writer.writeEndObject();
165                    } else {
166                        //
167                        // Standard property
168                        writer.writeStringField(key,value.toString());
169                    }
170                }
171                writer.writeEndObject();
172            }
173
174            writer.writeEndObject();
175        } catch (IOException e) {
176            throw new ConfigWriterException(e);
177        }
178    }
179
180    @Override
181    public void writeEndComponents() throws ConfigWriterException {
182        try {
183            writer.writeEndArray();
184        } catch (IOException e) {
185            throw new ConfigWriterException(e);
186        }
187    }
188
189    @Override
190    public void close() throws ConfigWriterException {
191        try {
192            writer.close();
193        } catch (IOException e) {
194            throw new ConfigWriterException(e);
195        }
196    }
197}