/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.eas.client.model.store;
import com.eas.client.metadata.Field;
import com.eas.client.metadata.ForeignKeySpec;
import com.eas.client.metadata.Parameter;
import com.eas.client.metadata.PrimaryKeySpec;
import com.eas.client.model.Entity;
import com.eas.client.model.Model;
import com.eas.client.model.Relation;
import com.eas.client.model.visitors.ModelVisitor;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
*
* @author mg
* @param <E>
* @param <M>
*/
public abstract class Model2XmlDom<E extends Entity<M, ?, E>, M extends Model<E, ?>> implements ModelVisitor<E, M> {
protected final static String YES_STRING = "yes";
protected final static String NO_STRING = "no";
public final static String DATAMODEL_TAG_NAME = "datamodel";
public final static String PARAMETER_TAG_NAME = "parameter";
public final static String PARAMETERS_TAG_NAME = "parameters";
public final static String ENTITY_TAG_NAME = "entity";
public final static String FIELDS_ENTITY_TAG_NAME = "fieldsEntity";
public final static String PARAMETERS_ENTITY_TAG_NAME = "parametersEntity";
public final static String RELATION_TAG_NAME = "relation";
public final static String LIGHT_RELATION_TAG_NAME = "lightRelation";
public final static String PRIMARY_KEYS_TAG_NAME = "primaryKeys";
public final static String FOREIGN_KEYS_TAG_NAME = "foreignKeys";
public final static String PRIMARY_KEY_TAG_NAME = "primaryKey";
public final static String FOREIGN_KEY_TAG_NAME = "foreignKey";
// setup documents framework
protected static DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// declaring documents framework
protected DocumentBuilder builder;
protected Document doc;
protected Node currentNode;
protected Model2XmlDom() {
super();
try {
// setup documents framework
builder = factory.newDocumentBuilder();
} catch (ParserConfigurationException ex) {
builder = null;
Logger.getLogger(Model2XmlDom.class.getName()).log(Level.SEVERE, null, ex);
}
}
protected Document model2XmlDom(M aModel) {
if (aModel != null && builder != null) {
doc = builder.newDocument();
doc.setXmlStandalone(true);
currentNode = doc;
aModel.accept((ModelVisitor<E, Model<E, ?>>)this);
return doc;
}
return null;
}
public void reset() {
doc = null;
currentNode = null;
}
public void writeModel(M aModel) {
if (aModel != null) {
Element datamodelNode = doc.createElement(DATAMODEL_TAG_NAME);
currentNode.appendChild(datamodelNode);
currentNode = datamodelNode;
writeEntities(aModel);
writeRelations(aModel);
}
}
protected void writeRelations(M aModel) {
if (aModel.getRelations() != null) {
aModel.getRelations().stream().forEach((relation) -> {
relation.accept(this);
});
}
}
protected void writeEntities(M aModel) throws DOMException {
if (aModel.getEntities() != null) {
aModel.getEntities().values().stream().forEach((entity) -> {
entity.accept(this);
});
}
}
public static final String NAME_ATTR_NAME = "name";
public static final String DATASOURCE_NAMEE_ATTR_NAME = "Name";
public static final String DATASOURCE_TITLE_ATTR_NAME = "Title";
public static final String DESCRIPTION_ATTR_NAME = "description";
public static final String TYPE_ATTR_NAME = "type";
public static final String SIZE_ATTR_NAME = "size";
public static final String SCALE_ATTR_NAME = "scale";
public static final String PRECISION_ATTR_NAME = "precision";
public static final String SIGNED_ATTR_NAME = "signed";
public static final String NULLABLE_ATTR_NAME = "nullable";
public static final String MODE_ATTR_NAME = "parameterMode";
public static final String IS_PK_ATTR_NAME = "isPk";
public static final String FK_TAG_NAME = "fk";
public static final String SELECTION_FORM_TAG_NAME = "selectionForm";
public static final String DEFAULT_VALUE_TAG_NAME = "defaultValue";
public static final String CLASS_HINT_TAG_NAME = "classHint";
@Override
public void visit(Field aField) {
if (aField != null) {
Element node = doc.createElement(PARAMETER_TAG_NAME);
currentNode.appendChild(node);
node.setAttribute(NAME_ATTR_NAME, aField.getName());
node.setAttribute(DESCRIPTION_ATTR_NAME, aField.getDescription());
node.setAttribute(TYPE_ATTR_NAME, aField.getType());
node.setAttribute(NULLABLE_ATTR_NAME, String.valueOf(aField.isNullable()));
if (aField instanceof Parameter) {
node.setAttribute(SELECTION_FORM_TAG_NAME, String.valueOf(((Parameter) aField).getSelectionForm()));
Object ov = ((Parameter) aField).getDefaultValue();
if (ov != null) {
Element dvNode = doc.createElement(DEFAULT_VALUE_TAG_NAME);
node.appendChild(dvNode);
dvNode.setAttribute(CLASS_HINT_TAG_NAME, ov.getClass().getSimpleName());
dvNode.setNodeValue(ov.toString());
}
node.setAttribute(MODE_ATTR_NAME, String.valueOf(((Parameter) aField).getMode()));
}
if (aField.isPk()) {
node.setAttribute(IS_PK_ATTR_NAME, String.valueOf(aField.isPk()));
}
ForeignKeySpec lfk = aField.getFk();
if (lfk != null) {
Node lcurrentNode = currentNode;
try {
currentNode = node;
visit(lfk.getReferee());
} finally {
currentNode = lcurrentNode;
}
}
}
}
public static final String ENTITY_ID_ATTR_NAME = "entityId";
public static final String QUERY_ID_ATTR_NAME = "queryId";
public static final String TABLE_DB_ID_ATTR_NAME = "tableDbId";
public static final String TABLE_SCHEMA_NAME_ATTR_NAME = "tableSchemaName";
public static final String TABLE_NAME_ATTR_NAME = "tableName";
public static final String ENTITY_TABLE_ALIAS = "tableAlias";
public static final String ENTITY_LOCATION_X = "entityLocationX";
public static final String ENTITY_LOCATION_Y = "entityLocationY";
public static final String ENTITY_SIZE_WIDTH = "entityWidth";
public static final String ENTITY_SIZE_HEIGHT = "entityHeight";
public static final String ENTITY_ICONIFIED = "entityIconified";
protected void writeEntityDesignAttributes(Element node, E entity) {
node.setAttribute(ENTITY_LOCATION_X, String.valueOf(entity.getX()));
node.setAttribute(ENTITY_LOCATION_Y, String.valueOf(entity.getY()));
node.setAttribute(ENTITY_SIZE_WIDTH, String.valueOf(entity.getWidth()));
node.setAttribute(ENTITY_SIZE_HEIGHT, String.valueOf(entity.getHeight()));
node.setAttribute(ENTITY_ICONIFIED, String.valueOf(entity.isIconified()));
}
public static final String LEFT_ENTITY_ID_ATTR_NAME = "leftEntityId";
public static final String LEFT_ENTITY_FIELD_ATTR_NAME = "leftEntityFieldName";
public static final String LEFT_ENTITY_PARAMETER_ATTR_NAME = "leftEntityParameterName";
public static final String RIGHT_ENTITY_ID_ATTR_NAME = "rightEntityId";
public static final String RIGHT_ENTITY_FIELD_ATTR_NAME = "rightEntityFieldName";
public static final String RIGHT_ENTITY_PARAMETER_ATTR_NAME = "rightEntityParameterName";
public static final String POLYLINE_ATTR_NAME = "polyline";
@Override
public void visit(Relation<E> aRelation) {
writeRelation(aRelation, doc.createElement(RELATION_TAG_NAME));
}
protected void writeRelation(Relation<E> relation, Element node) {
if (relation != null && relation.getLeftField() != null && relation.getRightField() != null) {
currentNode.appendChild(node);
assert relation.getLeftEntity() != null : " A relation without left side detected";
node.setAttribute(LEFT_ENTITY_ID_ATTR_NAME, String.valueOf(relation.getLeftEntity().getEntityId()));
if (relation.isLeftField()) {
node.setAttribute(LEFT_ENTITY_FIELD_ATTR_NAME, relation.getLeftField().getName());
} else {
node.setAttribute(LEFT_ENTITY_PARAMETER_ATTR_NAME, relation.getLeftParameter().getName());
}
assert relation.getRightEntity() != null : " A relation without right side detected";
node.setAttribute(RIGHT_ENTITY_ID_ATTR_NAME, String.valueOf(relation.getRightEntity().getEntityId()));
if (relation.isRightField()) {
node.setAttribute(RIGHT_ENTITY_FIELD_ATTR_NAME, relation.getRightField().getName());
} else {
node.setAttribute(RIGHT_ENTITY_PARAMETER_ATTR_NAME, relation.getRightParameter().getName());
}
if (relation.getXs() != null && relation.getYs() != null && relation.getXs().length == relation.getYs().length) {
node.setAttribute(POLYLINE_ATTR_NAME, polylineToString(relation));
}
}
}
private String polylineToString(Relation<E> relation) {
if (relation.getXs() != null && relation.getYs() != null && relation.getXs().length == relation.getYs().length) {
StringBuilder sb = new StringBuilder();
int[] xs = relation.getXs();
int[] ys = relation.getYs();
for (int i = 0; i < xs.length; i++) {
if (i > 0) {
sb.append(" ");
}
sb.append(xs[i]).append(";").append(ys[i]);
}
return sb.toString();
} else {
return null;
}
}
private void visit(PrimaryKeySpec pk) {
if (pk != null) {
Element node = doc.createElement(PRIMARY_KEY_TAG_NAME);
currentNode.appendChild(node);
if (pk.getCName() != null) {
node.setAttribute(CONSTRAINT_NAME_ATTR_NAME, pk.getCName());
}
if (pk.getSchema() != null) {
node.setAttribute(CONSTRAINT_SCHEMA_ATTR_NAME, pk.getSchema());
}
node.setAttribute(CONSTRAINT_TABLE_ATTR_NAME, pk.getTable());
node.setAttribute(CONSTRAINT_FIELD_ATTR_NAME, pk.getField());
}
}
//public static final String FIELD_NAME_ATTR_NAME = "updateRule";
public static final String CONSTRAINT_NAME_ATTR_NAME = "name";
public static final String CONSTRAINT_DBID_ATTR_NAME = "DbId";
public static final String CONSTRAINT_SCHEMA_ATTR_NAME = "schema";
public static final String CONSTRAINT_TABLE_ATTR_NAME = "table";
public static final String CONSTRAINT_FIELD_ATTR_NAME = "field";
/*
*
* WARNING! This is very useful code. It is not used because foreign key
* information is serialized and deserialized within relations
* serialization/deserialization.
*
*
* private void visit(ForeignKeySpec fk) { if (fk != null) { Element node =
* doc.createElement(FOREIGN_KEY_TAG_NAME);
*
* node.setAttribute(CONSTRAINT_NAME_ATTR_NAME, fk.getCName());
* node.setAttribute(CONSTRAINT_SCHEMA_ATTR_NAME, fk.getSchema());
* node.setAttribute(CONSTRAINT_TABLE_ATTR_NAME, fk.getTable());
* node.setAttribute(CONSTRAINT_FIELD_ATTR_NAME, fk.getField());
*
* node.setAttribute(DEFERRABLE_ATTR_NAME,
* String.valueOf(fk.getFkDeferrable()));
* node.setAttribute(DELETE_ATTR_NAME,
* String.valueOf(fk.getFkDeleteRule()));
* node.setAttribute(UPDATE_ATTR_NAME,
* String.valueOf(fk.getFkUpdateRule()));
*
* currentNode.appendChild(node); PrimaryKeySpec pk = fk.getReferee(); if
* (pk != null) { Node lcurrentNode = currentNode; try { currentNode = node;
* visit(pk); } finally { currentNode = lcurrentNode; } } } }
*/
public static final String DATAMODEL_DB_ID = "datamodelDbId";
public static final String DATAMODEL_DB_SCHEMA_NAME = "datamodelSchemaName";
public static final String DATAMODEL_DATASOURCE = "datasource";
public static final String DATAMODEL_DATASOURCE_SCHEMA_NAME = "schema";
}