
org.hyperledger.composer.bna.model.Model Maven / Gradle / Ivy
The newest version!
/*
* Copyright IBM Corp. 2017 All Rights Reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.composer.bna.model;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import org.hyperledger.composer.annotation.Asset;
import org.hyperledger.composer.annotation.Concept;
import org.hyperledger.composer.annotation.Participant;
import org.hyperledger.composer.annotation.Transaction;
import org.hyperledger.composer.bna.part.CtoPart;
public class Model {
public static final List> MODEL_ANNOTATIONS
= Arrays.asList(Asset.class, Participant.class, Transaction.class, Concept.class);
private final List fields;
private final CtoPart ctoPart;
String name;
Model.ModelType type;
private String namespace;
private FieldModel primaryKey;
private String parentName;
/**
* constructor.
*
* @param ctoPart the {@code CtoPart}
*/
public Model(CtoPart ctoPart) {
this.ctoPart = ctoPart;
this.ctoPart.addEntry(this);
this.fields = new LinkedList<>();
}
static boolean isPointerType(Field field) {
for (Class extends Annotation> annotation : MODEL_ANNOTATIONS) {
if (checkFieldAnnotation(field, annotation)) {
return true;
}
}
return false;
}
static boolean checkFieldAnnotation(Field field, Class extends Annotation> annotation) {
Class> type = field.getType();
type = type.isArray() ? type.getComponentType() : type;
return type.isAnnotationPresent(annotation);
}
public Model name(String name) {
this.name = name;
return this;
}
public Model namespace(String namespace) {
this.namespace = namespace;
return this;
}
public Model type(Class extends Annotation> type) {
this.type = ModelType.valueOf(type.getSimpleName().toUpperCase());
return this;
}
/**
* set the parent for this {@code Model}.
*
* @param parentNamespace namespace of the parent
* @param parentName name of the parent
* @return this {@code Model}
*/
public Model parent(String parentNamespace, String parentName) {
this.parentName = parentName;
this.addDependency(parentNamespace, parentNamespace + '.' + parentName);
return this;
}
/**
* add a {@code FieldModel} for this {@code Model}.
*
* @param field the {@code FieldModel}
* @param isPrimary true if the {@code FieldModel} is the primary key
* @return this {@code Model}
*/
public Model addField(FieldModel field, boolean isPrimary) {
if (type == ModelType.TRANSACTION) {
String transactionName = namespace + "." + name;
if (isPrimary) {
throw new IllegalArgumentException(
"No primary key for transaction type:" + transactionName);
}
if ("transactionId".equals(field.name())) {
throw new IllegalArgumentException(
"No field named 'transactionId' for transaction type:" + transactionName);
}
}
if (isPrimary && primaryKey != null) {
throw new IllegalArgumentException(
String.format("Duplicate primary key: %s, %s", primaryKey.name(), field.name()));
}
this.fields.add(field);
this.addDependency(field.namespace(), field.dependency());
if (isPrimary) {
this.primaryKey = field;
}
return this;
}
private void addDependency(String namespace, String dependency) {
if (dependency != null && !this.namespace.equals(namespace)) {
this.ctoPart.addEntry(dependency);
}
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(type.toString().toLowerCase());
builder.append(' ');
builder.append(name);
switch (type) {
case TRANSACTION:
case CONCEPT:
if (parentName != null) {
builder.append(" extends ");
builder.append(parentName);
}
break;
default:
if (primaryKey == null) {
if (parentName == null) {
throw new IllegalArgumentException(
"primary key of String type must be given for " + this.namespace + "." + this.name);
}
builder.append(" extends ");
builder.append(parentName);
} else {
builder.append(" identified by ");
builder.append(primaryKey.name());
}
}
builder.append(" {\n");
for (FieldModel field : fields) {
builder.append(field.toString()).append('\n');
}
builder.append("}\n");
return builder.toString();
}
public enum ModelType {
ASSET, PARTICIPANT, CONCEPT, TRANSACTION, ENUM
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy