Java tutorial
/******************************************************************************* * 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 + "'"); } } } }