All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hpe.adm.nga.sdk.model.ModelParser Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2016-2023 Open Text.
 *
 * The only warranties for products and services of Open Text and
 * its affiliates and licensors (“Open Text”) are as may be set forth
 * in the express warranty statements accompanying such products and services.
 * Nothing herein should be construed as constituting an additional warranty.
 * Open Text shall not be liable for technical or editorial errors or
 * omissions contained herein. The information contained herein is subject
 * to change without notice.
 *
 * Except as specifically indicated otherwise, this document contains
 * confidential information and a valid license is required for possession,
 * use or copying. If this work is provided to the U.S. Government,
 * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
 * Computer Software Documentation, and Technical Data for Commercial Items are
 * licensed to the U.S. Government under vendor's standard commercial license.
 *
 * 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.hpe.adm.nga.sdk.model;

import com.hpe.adm.nga.sdk.entities.OctaneCollection;
import java.time.format.DateTimeParseException;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.ZonedDateTime;
import java.util.*;
import java.util.stream.IntStream;

public final class ModelParser {
    private static final String JSON_DATA_NAME = "data";
    private static final String JSON_ERRORS_NAME = "errors";
    private static final String JSON_TOTAL_COUNT_NAME = "total_count";
    private static final String JSON_EXCEEDS_TOTAL_COUNT_NAME = "exceeds_total_count";
    private static final String LOGGER_INVALID_FIELD_SCHEME_FORMAT = "{} field scheme is invalid";

    private final Logger logger = LoggerFactory.getLogger(ModelParser.class.getName());

    private static ModelParser modelParser = new ModelParser();

    private ModelParser() {
    }

    public static ModelParser getInstance() {
        return modelParser;
    }

    /**
     * get a new json object based on a given EntityModel object
     *
     * @param entityModel the given entity model object
     * @return new json object based on a given EntityModel object
     */
    public final JSONObject getEntityJSONObject(EntityModel entityModel) {
        return getEntityJSONObject(entityModel, false);
    }

    /**
     * get a new json object based on a given EntityModel object
     *
     * @param entityModel the given entity model object
     * @param onlyDirty   Return only dirty fields (used for updates)
     * @return new json object based on a given EntityModel object
     */
    @SuppressWarnings("rawtypes")
    public final JSONObject getEntityJSONObject(EntityModel entityModel, boolean onlyDirty) {

        Collection fieldModels = onlyDirty ? entityModel.getDirtyValues() : entityModel.getValues();
        JSONObject objField = new JSONObject();
        fieldModels.forEach((i) -> {
            Object value = i.getJSONValue();
            objField.put(i.getName(), Objects.isNull(value) ? JSONObject.NULL : value);
        });

        return objField;
    }

    /**
     * get a new json object based on a given EntityModel list
     *
     * @param entitiesModels - Collection of entities models
     * @return new json object conatin entities data
     */
    public final JSONObject getEntitiesJSONObject(Collection entitiesModels) {
        return getEntitiesJSONObject(entitiesModels, false);
    }

    /**
     * get a new json object based on a given EntityModel list
     *
     * @param entitiesModels - Collection of entities models
     * @param onlyDirty      Converts only dirty fields (relevant for updating entity)
     * @return new json object conatin entities data
     */
    public final JSONObject getEntitiesJSONObject(Collection entitiesModels, boolean onlyDirty) {

        JSONObject objBase = new JSONObject();
        JSONArray objEntities = new JSONArray();
        objBase.put(JSON_DATA_NAME, objEntities);
        objBase.put(JSON_TOTAL_COUNT_NAME, entitiesModels.size());
        objBase.put(JSON_EXCEEDS_TOTAL_COUNT_NAME, false);
        entitiesModels.forEach((i) -> objEntities.put(getEntityJSONObject(i, onlyDirty)));

        return objBase;
    }

    /**
     * get a new EntityModel object based on json object
     *
     * @param jsonEntityObj - json object
     * @return new EntityModel object
     */
    @SuppressWarnings("rawtypes")
    public EntityModel getEntityModel(JSONObject jsonEntityObj) {

        Set fieldModels = new HashSet<>();
        Iterator keys = jsonEntityObj.keys();
        EntityModel entityModel;

        while (keys.hasNext()) {

            FieldModel fldModel;
            String strKey = (String) keys.next();
            Object aObj = jsonEntityObj.get(strKey);
            if (aObj == JSONObject.NULL) {
                fldModel = new EmptyFieldModel(strKey);
            } else if (aObj instanceof Long || aObj instanceof Integer) {
                fldModel = new LongFieldModel(strKey, Long.parseLong(aObj.toString()));
            } else if (aObj instanceof Double || aObj instanceof Float) {
                fldModel = new FloatFieldModel(strKey, Float.parseFloat(aObj.toString()));
            } else if (aObj instanceof Boolean) {
                fldModel = new BooleanFieldModel(strKey, Boolean.parseBoolean(aObj.toString()));
            } else if (aObj instanceof JSONArray) {
                fldModel = new ArrayFieldModel(strKey, aObj.toString());
            } else if (aObj instanceof JSONObject) {

                JSONObject fieldObject = jsonEntityObj.getJSONObject(strKey);

                if (!fieldObject.isNull(JSON_DATA_NAME) && fieldObject.get(JSON_DATA_NAME) instanceof JSONArray) {

                    Collection entities = getEntities(aObj.toString());
                    fldModel = new MultiReferenceFieldModel(strKey, entities);
                } else if (!fieldObject.isNull("type") && !fieldObject.isNull("id")) {
                    EntityModel ref = getEntityModel(jsonEntityObj.getJSONObject(strKey));
                    fldModel = new ReferenceFieldModel(strKey, ref);
                } else {
                    fldModel = new ObjectFieldModel(strKey, aObj.toString());
                }

            } else if (aObj instanceof String) {

                try {
                    ZonedDateTime zonedDateTime = ZonedDateTime.parse(aObj.toString());
                    fldModel = new DateFieldModel(strKey, zonedDateTime);
                } catch (DateTimeParseException e) {
                    fldModel = new StringFieldModel(strKey, aObj.toString());
                }

            } else {
                logger.debug(LOGGER_INVALID_FIELD_SCHEME_FORMAT, strKey);
                continue; //do not put it inside the model object to avoid a null pointer exception
            }

            fieldModels.add(fldModel);
        }

        entityModel = new EntityModel(fieldModels, EntityModel.EntityState.CLEAN);
        return entityModel;
    }

    /**
     * get a entity model collection based on a given json string
     *
     * @param json The JSON to parse
     * @return entity model collection based on a given json string
     */
    public OctaneCollection getEntities(String json) {
        JSONTokener tokener = new JSONTokener(json);
        JSONObject jsonObj = new JSONObject(tokener);
        JSONArray jsonDataArr = jsonObj.getJSONArray(JSON_DATA_NAME);

        final OctaneCollection entityModels;
        if (jsonObj.has(JSON_EXCEEDS_TOTAL_COUNT_NAME) && jsonObj.has(JSON_TOTAL_COUNT_NAME)) {
            final boolean exceedsTotalAmount = jsonObj.getBoolean("exceeds_total_count");
            final int totalCount = jsonObj.getInt("total_count");
            entityModels = new OctaneCollectionImpl<>(totalCount, exceedsTotalAmount);
        } else {
            entityModels = new OctaneCollectionImpl<>();
        }
        IntStream.range(0, jsonDataArr.length()).forEach((i) -> entityModels.add(getEntityModel(jsonDataArr.getJSONObject(i))));

        return entityModels;
    }

    /**
     * Checks the message for a list of errors
     *
     * @param json The json to parse
     * @return Whether there is a list of errors
     */
    public boolean hasErrorModels(String json) {
        JSONTokener tokener = new JSONTokener(json);
        JSONObject jsonObj = new JSONObject(tokener);
        return jsonObj.has(JSON_ERRORS_NAME) && jsonObj.get(JSON_ERRORS_NAME) instanceof JSONArray;
    }

    /**
     * Checks the message for an error
     *
     * @param json The json to parse
     * @return Whether there is an error
     */
    public boolean hasErrorModel(String json) {
        JSONTokener tokener = new JSONTokener(json);
        JSONObject jsonObj = new JSONObject(tokener);
        return jsonObj.has("error_code") && jsonObj.get("error_code") instanceof String;
    }

    /**
     * Checks the message for a higher-level servlet error
     *
     * @param json The json to parse
     * @return Whether there is a higher level servlet error
     */
    public boolean hasServletError(String json) {
        JSONTokener tokener = new JSONTokener(json);
        JSONObject jsonObj = new JSONObject(tokener);
        return jsonObj.has("message") && jsonObj.get("message") instanceof String;
    }

    /**
     * GetEntities Error models based on a given error json string
     *
     * @param json - json string with error information
     * @return collection of error models
     */
    public Collection getErrorModels(String json) {

        JSONTokener tokener = new JSONTokener(json);
        JSONObject jsonObj = new JSONObject(tokener);
        JSONArray jsonErrArr = jsonObj.getJSONArray(JSON_ERRORS_NAME);
        Collection ErrModels = new ArrayList<>();
        IntStream.range(0, jsonErrArr.length()).forEach((i) -> ErrModels.add(getErrorModelFromjson(jsonErrArr.getJSONObject(i).toString())));

        return ErrModels;
    }

    /**
     * GetEntities Error model based on a given error json string
     *
     * @param json - json string with error information
     * @return error model
     */
    @SuppressWarnings("rawtypes")
    public ErrorModel getErrorModelFromjson(String json) {

        JSONTokener tokener = new JSONTokener(json);
        JSONObject jsonErrObj = new JSONObject(tokener);

        Set fieldModels = new HashSet<>();
        Iterator keys = jsonErrObj.keys();

        while (keys.hasNext()) {

            String strKey = (String) keys.next();
            Object aObj = jsonErrObj.get(strKey);

            FieldModel fldModel;

            if (aObj == JSONObject.NULL) {
                fldModel = new ReferenceErrorModel(strKey, null);
            } else if (aObj instanceof JSONObject) {
                EntityModel ref = getEntityModel(jsonErrObj.getJSONObject(strKey));
                fldModel = new ReferenceFieldModel(strKey, ref);
            } else {

                fldModel = new StringFieldModel(strKey, aObj.toString());
            }

            fieldModels.add(fldModel);

        }


        return new ErrorModel(fieldModels);
    }

    /**
     * Parses the servlet error and extracts the underlying message that was set by Octane that can then be used by the
     * exception
     *
     * @param json The json to parse
     * @return The errormodel with all extracted errors
     */
    public ErrorModel getErrorModelFromServletJson(String json) {
        final ErrorModel firstLevelModel = getErrorModelFromjson(json);
        final String messageInJson = firstLevelModel.getValue("message").getValue().toString();
        final ErrorModel errorModelFromjson = getErrorModelFromjson(messageInJson.replaceAll(""", "\""));
        errorModelFromjson.getValues().forEach(firstLevelModel::setValue);

        return firstLevelModel;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy