com.synflow.cx.internal.instantiation.properties.EntityPropertiesChecker.java Source code

Java tutorial

Introduction

Here is the source code for com.synflow.cx.internal.instantiation.properties.EntityPropertiesChecker.java

Source

/*******************************************************************************
 * Copyright (c) 2013-2014 Synflow SAS.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Matthieu Wipliez - initial API and implementation and/or initial documentation
 *******************************************************************************/
package com.synflow.cx.internal.instantiation.properties;

import static com.synflow.core.IProperties.ACTIVE_HIGH;
import static com.synflow.core.IProperties.ACTIVE_LOW;
import static com.synflow.core.IProperties.DEFAULT_CLOCK;
import static com.synflow.core.IProperties.PROP_ACTIVE;
import static com.synflow.core.IProperties.PROP_CLOCKS;
import static com.synflow.core.IProperties.PROP_NAME;
import static com.synflow.core.IProperties.PROP_RESET;
import static com.synflow.core.IProperties.PROP_TEST;
import static com.synflow.core.IProperties.RESET_ASYNCHRONOUS;
import static com.synflow.core.IProperties.RESET_SYNCHRONOUS;
import static com.synflow.cx.CxConstants.PROP_TYPE;
import static com.synflow.cx.CxConstants.TYPE_COMBINATIONAL;

import java.util.HashSet;
import java.util.Map.Entry;
import java.util.Set;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.synflow.cx.CxUtil;
import com.synflow.cx.cx.Instantiable;
import com.synflow.cx.cx.Variable;

/**
 * This class defines a properties checker for an entity.
 * 
 * @author Matthieu Wipliez
 * 
 */
public class EntityPropertiesChecker extends PropertiesChecker {

    public EntityPropertiesChecker(IJsonErrorHandler handler) {
        super(handler);
    }

    private void checkClocksDeclared(JsonObject properties) {
        applyClockShortcut(properties);

        // if there are no clocks, or if they are not valid, use default clock
        JsonElement clocks = properties.get(PROP_CLOCKS);
        if (clocks == null || !checkClockArray(clocks)) {
            JsonArray clocksArray = new JsonArray();
            clocksArray.add(DEFAULT_CLOCK);
            properties.add(PROP_CLOCKS, clocksArray);
        }
    }

    /**
     * Checks the given properties of the <code>instantiable</code>.
     * 
     * @param instantiable
     *            a Cx instantiable
     * @param properties
     *            JSON properties
     */
    public void checkProperties(Instantiable instantiable, JsonObject properties) {
        checkTest(instantiable, properties.get(PROP_TEST));

        JsonElement type = properties.get(PROP_TYPE);
        if (type != null) {
            if (type.isJsonPrimitive()) {
                JsonPrimitive entityType = properties.getAsJsonPrimitive(PROP_TYPE);
                if (TYPE_COMBINATIONAL.equals(entityType)) {
                    // set an empty list of clocks, set no reset
                    properties.add(PROP_CLOCKS, new JsonArray());
                    properties.add(PROP_RESET, null);
                    return;
                } else {
                    handler.addError(entityType, "the only valid value of type is 'combinational', ignored.");
                }
            } else {
                handler.addError(type, "type must be a string");
            }
        }

        checkClocksDeclared(properties);
        checkResetDeclared(properties);
    }

    /**
     * Checks that the 'reset' property is properly declared.
     * 
     * @param properties
     *            properties
     */
    private void checkResetDeclared(JsonObject properties) {
        JsonElement reset = properties.get(PROP_RESET);
        if (reset == null) {
            reset = new JsonObject();
            properties.add(PROP_RESET, reset);
        }

        if (reset.isJsonObject()) {
            JsonObject resetObj = reset.getAsJsonObject();

            JsonPrimitive type = resetObj.getAsJsonPrimitive(PROP_TYPE);
            if (type == null || !RESET_ASYNCHRONOUS.equals(type) && !RESET_SYNCHRONOUS.equals(type)) {
                // default is asynchronous reset
                resetObj.add(PROP_TYPE, RESET_ASYNCHRONOUS);
            }

            JsonPrimitive active = resetObj.getAsJsonPrimitive(PROP_ACTIVE);
            if (active == null || !ACTIVE_HIGH.equals(active) && !ACTIVE_LOW.equals(active)) {
                // default is active low reset
                resetObj.add(PROP_ACTIVE, ACTIVE_LOW);
            }

            if (!resetObj.has(PROP_NAME)) {
                // compute default name
                if (ACTIVE_LOW.equals(resetObj.getAsJsonPrimitive(PROP_ACTIVE))) {
                    resetObj.addProperty(PROP_NAME, "reset_n");
                } else {
                    resetObj.addProperty(PROP_NAME, "reset");
                }
            }
        }
    }

    /**
     * Checks the "test" property. We use an instantiable because the entity is not translated when
     * we do this check (in the skeleton maker).
     * 
     * @param instantiable
     *            instantiable
     * @param test
     *            test element
     */
    private void checkTest(Instantiable instantiable, JsonElement test) {
        if (test == null) {
            return;
        }

        if (!test.isJsonObject()) {
            handler.addError(test, "test must be an object");
        }

        JsonObject objTest = test.getAsJsonObject();
        Set<String> ports = new HashSet<>();
        for (Variable port : CxUtil.getPorts(instantiable.getPortDecls())) {
            String name = port.getName();
            ports.add(name);

            if (!objTest.has(name)) {
                handler.addError(objTest, "missing test values for port '" + name + "'");
                continue;
            }

            JsonElement values = objTest.get(name);
            if (!values.isJsonArray()) {
                handler.addError(objTest, "test values for port '" + name + "' must be an array");
                continue;
            }
        }

        for (Entry<String, JsonElement> entry : objTest.entrySet()) {
            String name = entry.getKey();
            if (!ports.contains(name)) {
                handler.addError(objTest, "unknown port '" + name + "'");
            }
        }
    }

}