Commit 64adf16a authored by mathieu's avatar mathieu

-Improve middleground importation (add parameters and units)

-Add flag for unlinked elements
-Add flow property window in process tab
-Improve navigation in the process tree
-Improve JSONFormater to allow use a formater in an other formater
-Improve logging
-Improve errors handling
parent f533f830
......@@ -108,7 +108,7 @@ public class IED extends UBUBIController {
e.printStackTrace();
}
trace.setDescrition("Model:"+converter.getBimModel().getId()+";Duration:"+(end.getTime()-begin.getTime())+"ms");
trace.setDescrition("Model:"+converter.getBimModel().getId()+";Duration:"+(end.getTime()-begin.getTime())+"ms;"+converter.getLogDetails());
JPA.em().persist(trace);
return ok(converter.getBimModel().getId()+"");
......
......@@ -173,22 +173,8 @@ public class BIMModel extends UBUBIController
@Transactional(readOnly = true)
public Result getForeGroundProcess2(Long idModel)
{
Date begin = new Date();
Query query= JPA.em().createQuery("Select bp " +
"From BIMProcess bp inner join bp.model bm " +
"Where bm.id=:BIMModelId",BIMProcess.class);
query.setHint("javax.persistence.loadgraph",JPA.em().getEntityGraph("BIMProcess.foreground"));
query.setParameter("BIMModelId",idModel);
List<BIMProcess> lst =query.getResultList();
String result = "{"+JSONUtil.parseArray("lst",lst,JSONFormater.ForegroundFormater)+"}";
Date end = new Date();
System.out.println("Time:"+(end.getTime()-begin.getTime())+"ms");
return jsonResult(ok(result));
//Test
return jsonResult(ok(""));
}
@Transactional(readOnly = true)
......@@ -199,9 +185,9 @@ public class BIMModel extends UBUBIController
"from (SELECT bp.process_id, " +
"count(distinct e.id) as QtyObjTypeLink, " +
"count(distinct if(not isNull(f.id),e.id,null)) as QtyObjTypeLinkMat, " +
"count(distinct if(isNull(f.id),e.id,null)) as QtyObjTypeLinkBG, " +
"count(distinct if(isNull(f2.id) and not isNull(e3.id),e.id,null)) as QtyMatLinkBG, " +
"ifnull(group_concat(distinct if(isNull(f2.id) and isNull(e3.id),e2.f_owner,null) separator \";\"),\"\") as lstMat " +
"count(distinct if(isNull(f.id) and e.resulting_amount_value<>0,e.id,null)) as QtyObjTypeLinkBG, " +
"count(distinct if(isNull(f2.id) and not isNull(e3.id) and e3.resulting_amount_value<>0,e3.id,null)) as QtyMatLinkBG, " +
"ifnull(group_concat(distinct if(not(isNull(f2.id) and not isNull(e3.id) and e3.resulting_amount_value<>0),e2.f_owner,null) separator \";\"),\"\") as lstMat " +
"FROM tbl_BIMProcesses bp left join tbl_exchanges e on(e.f_owner=bp.process_id and e.is_input=1) " +
"left join tbl_BIMFlows f on (f.flow_id=e.f_flow and f.bimEntityType=\"BIMMaterial\") " +
"left join tbl_exchanges e2 on(e2.f_flow=flow_id and e2.is_input=0) " +
......
......@@ -24,6 +24,7 @@ package controllers.API.model;
import com.fasterxml.jackson.databind.JsonNode;
import controllers.API.model.generic.DataController;
import controllers.API.model.generic.DataErrorController;
import models.LCA.BIMEntityType;
import org.openlca.core.model.*;
import org.openlca.core.model.Category;
......@@ -32,6 +33,7 @@ import org.openlca.core.model.Unit;
import play.db.jpa.JPA;
import play.db.jpa.Transactional;
import play.mvc.Result;
import util.ErrorWrapper;
import util.JSONFormater;
import play.db.jpa.JPAApi;
import util.JSONUtil;
......@@ -43,7 +45,7 @@ import javax.persistence.NoResultException;
/**
* Created by mathieu on 10/12/2016.
*/
public class Exchange extends DataController<org.openlca.core.model.Exchange>
public class Exchange extends DataErrorController<org.openlca.core.model.Exchange>
{
@Inject
public Exchange(JPAApi api)
......@@ -53,8 +55,9 @@ public class Exchange extends DataController<org.openlca.core.model.Exchange>
}
@Override
protected org.openlca.core.model.Exchange allowUpdate(JsonNode modifiedObject, org.openlca.core.model.Exchange sourceObj,EntityManager em)
protected ErrorWrapper<org.openlca.core.model.Exchange> allowUpdate(JsonNode modifiedObject, ErrorWrapper<org.openlca.core.model.Exchange> obj, EntityManager em)
{
org.openlca.core.model.Exchange sourceObj = obj.getData();
//Modify the default Provider
if(modifiedObject.get("defaultProviderId")!=null)
{
......@@ -75,11 +78,12 @@ public class Exchange extends DataController<org.openlca.core.model.Exchange>
}
}
//TODO update formula
//Modify the amount formula
if(modifiedObject.get("amountFormula")!=null)
/*if(modifiedObject.get("amountFormula")!=null)
{
sourceObj.setAmountFormula(modifiedObject.get("amountValue").asText());
}
}*/
//Modify the amount
if(modifiedObject.get("amountValue")!=null)
......@@ -108,12 +112,14 @@ public class Exchange extends DataController<org.openlca.core.model.Exchange>
}
}
return sourceObj;
return obj;
}
@Override
protected org.openlca.core.model.Exchange allowInsert(JsonNode json, EntityManager em)
protected ErrorWrapper<org.openlca.core.model.Exchange> allowInsert(JsonNode json, EntityManager em)
{
ErrorWrapper<org.openlca.core.model.Exchange> errEx = new ErrorWrapper<>();
//TODO Add busness case rule
long idProcess = json.get("processId").asLong();
org.openlca.core.model.Process proc = em.find(org.openlca.core.model.Process.class,idProcess);
......@@ -125,6 +131,8 @@ public class Exchange extends DataController<org.openlca.core.model.Exchange>
return null;
org.openlca.core.model.Exchange ex = new org.openlca.core.model.Exchange();
errEx.setData(ex);
ex.setInput(json.get("isInput").asBoolean());
ex.setDefaultProviderId(json.get("defaultProviderId")!=null?json.get("defaultProviderId").asLong():0);
......@@ -148,11 +156,11 @@ public class Exchange extends DataController<org.openlca.core.model.Exchange>
ex.setFlowPropertyFactor(fpf);
proc.getExchanges().add(ex);
return ex;
return errEx;
}
@Override
protected boolean allowDelete(org.openlca.core.model.Exchange obj, EntityManager em)
protected boolean allowDelete(ErrorWrapper<org.openlca.core.model.Exchange> objWrapper, EntityManager em)
{
//TODO add business rule
/*Process sourceProc=null;
......@@ -184,6 +192,7 @@ public class Exchange extends DataController<org.openlca.core.model.Exchange>
//Verifify that is not
break;
}*/
org.openlca.core.model.Exchange obj=objWrapper.getData();
Boolean canDelete = !(!obj.isInput() && obj.getFlow().getFlowType()==FlowType.PRODUCT_FLOW);
if(canDelete)
......
This diff is collapsed.
......@@ -25,6 +25,7 @@ package controllers.API.model;
import controllers.API.model.generic.DataController;
import models.LCA.LCIResultSet;
import models.LCA.ProcessHistory;
import org.openlca.core.model.FlowPropertyFactor;
import org.openlca.core.model.Parameter;
import org.openlca.core.model.ParameterScope;
import org.openlca.expressions.FormulaInterpreter;
......@@ -158,6 +159,14 @@ public class Process extends DataController<org.openlca.core.model.Process>
return jsonResult(ok("{"+JSONUtil.parseArray("lst",retrievedProcess.getParameters(),JSONFormater.ParameterFormater)+"}"));
}
@Transactional
public Result getFlowPropertyFactor(Long id)
{
org.openlca.core.model.Process proc = JPA.em().find(org.openlca.core.model.Process.class,id);
List<FlowPropertyFactor> lstfpf = proc.getQuantitativeReference().getFlow().getFlowPropertyFactors();
return jsonResult(ok("{"+JSONUtil.parseArray("lst",lstfpf,JSONFormater.FlowPropertyFactorFormater)+"}"));
}
private List<Parameter> getGlobalParametersFromDB() {
Query query = JPA.em().createQuery("Select p from Parameter p where p.scope = :global");
......
......@@ -62,6 +62,7 @@ public class Router extends UBUBIController
routes.javascript.BIMModel.getFlow(),
routes.javascript.BIMModel.calculateResult(),
routes.javascript.BIMModel.getForeGroundProcess(),
routes.javascript.BIMProcess.all(),
routes.javascript.Process.getInfo(),
routes.javascript.Process.getInfoWithHistory(),
......@@ -70,6 +71,7 @@ public class Router extends UBUBIController
routes.javascript.Process.getGlobalParameters(),
routes.javascript.Process.setParameterFormula(),
routes.javascript.Process.getKmz(),
routes.javascript.Process.getFlowPropertyFactor(),
routes.javascript.Flow.getInfo(),
routes.javascript.Flow.getInfoWithHistory(),
......
package controllers.API.model.generic;
import com.fasterxml.jackson.databind.JsonNode;
import controllers.UBUBIController;
import play.db.jpa.JPA;
import play.db.jpa.JPAApi;
import play.db.jpa.Transactional;
import play.mvc.Result;
import util.ErrorWrapper;
import util.JSONErrorFormater;
import util.JSONFormater;
import util.JSONUtil;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import java.util.List;
public abstract class DataErrorController<T extends org.openlca.core.model.AbstractEntity> extends UBUBIController
{
private JSONErrorFormater<T> formater;
private Class<T> dataClass;
private String allQuery;
@Inject
public DataErrorController(JPAApi api)
{
super(api);
}
protected void init(Class<T> dataClass, JSONFormater<T> formater, String allQuery)
{
if(formater==null)
throw new NullPointerException();
this.formater=new JSONErrorFormater<>(formater);
this.dataClass=dataClass;
this.allQuery=allQuery;
}
@Transactional(readOnly = true)
public Result getInfo(Long id)
{
T returnVal = JPA.em().find(dataClass, id);
if (returnVal == null)
return jsonResult(notFound());
return jsonResult(ok(formater.parseDataOnly(returnVal)));
}
@Transactional(readOnly = true)
public Result all()
{
if(allQuery==null)
return jsonResult(unauthorized());
List<T> lstVal = null;
try
{
Query query = JPA.em().createQuery(allQuery);
lstVal = query.getResultList();
}
catch (NoResultException e) {}
StringBuilder sb = new StringBuilder();
sb.append("{");
sb.append(JSONUtil.parseArray("lst",lstVal,formater.getDataFormater()));
sb.append("}");
return jsonResult(ok(sb.toString()));
}
/*
* Override this methode to allow to create object
*
* return the object to insert, or null if unautorized
* */
protected ErrorWrapper<T> allowInsert(JsonNode json, EntityManager em)
{
return null;
}
@Transactional
public Result insert()
{
JsonNode json = request().body().asJson();
ErrorWrapper<T> val = allowInsert(json,JPA.em());
if(val==null || val.getData()==null)
return jsonResult(unauthorized());
JPA.em().persist(val.getData());
return jsonResult(ok(formater.parseObject(val)));
}
/*
* Override this methode to allow to update object
*
* return the modified object, or null if unautorized
* */
protected ErrorWrapper<T> allowUpdate(JsonNode modifiedObject, ErrorWrapper<T> sourceObj,EntityManager em)
{
return null;
}
@Transactional
public Result update(long id)
{
JsonNode modifiedObject = request().body().asJson();
ErrorWrapper<T> sourceObj = new ErrorWrapper<>(JPA.em().find(dataClass, id));
if (sourceObj == null)
return jsonResult(notFound());
ErrorWrapper<T> val = allowUpdate(modifiedObject,sourceObj,JPA.em());
if(val==null)
return jsonResult(unauthorized());
JPA.em().merge(val.getData());
return jsonResult(ok(formater.parseObject(val)));
}
/*
* Override this methode to allow to delete object
* */
protected boolean allowDelete(ErrorWrapper<T> obj, EntityManager em)
{
return false;
}
@Transactional
public Result delete(long id)
{
ErrorWrapper<T> returnVal = new ErrorWrapper<>(JPA.em().find(dataClass, id));
if (returnVal == null)
return jsonResult(notFound());
if(!allowDelete(returnVal,JPA.em()))
{
return jsonResult(unauthorized(EMPTY_REST_RESULT));
}
JPA.em().remove(returnVal.getData());
return jsonResult(ok(EMPTY_REST_RESULT));
}
}
......@@ -46,12 +46,6 @@ import java.io.Serializable;
@Entity
@Data
@Table(name="tbl_BIMProcesses")
@NamedEntityGraph(name = "BIMProcess.foreground",
attributeNodes = {@NamedAttributeNode(value = "process", subgraph = "process")},
subgraphs = {@NamedSubgraph(name = "process", attributeNodes = {
@NamedAttributeNode("exchanges"),
@NamedAttributeNode("quantitativeReference")
})})
public class BIMProcess
{
@Id
......
......@@ -9,7 +9,7 @@ import javax.persistence.*;
@Data
@Entity
@Table(name="tbl_middleground_structure")
public class middleground
public class Middleground
{
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
......@@ -25,8 +25,17 @@ public class middleground
private String unit;
private String ref;
@Column(nullable = true)
private Integer indication;
@Column(nullable = true) private Double kgbym3;
@Column(nullable = true) private Double kgbym2;
@Column(nullable = true) private String refDensity;
@Column(nullable = true) private Double rValueIn;
@Column(nullable = true) private Double rValue;
@Column(nullable = true) private String refRValue;
@Column(nullable = true) private Double thicknessMin;
@Column(nullable = true) private Double thicknessMax;
@Column(nullable = true) private Integer indicator;
@Column(name = "uuid_process",nullable = true)
private String uuidProcess;
......
package util;
import lombok.Getter;
import lombok.Setter;
public class ErrorWrapper<T>
{
@Getter @Setter private int errorCode=0;
@Getter @Setter private String errorTitle;
@Getter @Setter private String errorDescription;
@Getter @Setter private T data;
public ErrorWrapper() { this(null); }
public ErrorWrapper(T data)
{
this(data,0,null,null);
}
public ErrorWrapper(T data,int errorCode, String errorTitle, String errorDescription)
{
this.errorCode = errorCode;
this.errorTitle = errorTitle;
this.errorDescription = errorDescription;
this.data = data;
}
}
This diff is collapsed.
package util;
public class JSONErrorFormater<T> extends JSONFormater<ErrorWrapper<T>>
{
JSONFormater<T> formater;
public JSONErrorFormater(JSONFormater<T> formater)
{
this.formater=formater;
if(this.formater==null)
this.formater=new JSONFormater<T>()
{
@Override
protected String parse(T data) {
return "";
}
};
}
protected String parse(ErrorWrapper<T> data)
{
if(data==null)
return "";
String strResult=data.getData()==null?"":formater.parse(data.getData());
String error=parseError(data);
if("".compareTo(error)!=0)
{
if("".compareTo(strResult)!=0)
strResult+=",";
strResult+="error:{"+ error +"}";
}
return strResult;
}
private String parseError(ErrorWrapper<T> data)
{
String error="";
if(data!=null && data.getErrorCode()>0)
error = JSONUtil.parse("code",data.getErrorCode())+","+
JSONUtil.parse("title",data.getErrorTitle())+","+
JSONUtil.parse("description",data.getErrorDescription());
return error;
}
public String parseErrorOnly(ErrorWrapper<T> data)
{
String error = parseError(data);
if("".compareTo(error)!=0)
error+="{error:{"+error+"}}";
return error;
}
public String parseDataOnly(T data)
{
return data==null?"":formater.parseObject(data);
}
public JSONFormater<T> getDataFormater()
{
return this.formater;
}
}
This diff is collapsed.
......@@ -78,6 +78,17 @@ public class JSONUtil
return "\""+key+"\":\""+value.url()+"\"";
}
public static String parseJsonObject(String key, String jsonObjectContent)
{
String value = jsonObjectContent;
if(value==null || "".compareTo(value)==0)
value="null";
else
value="{"+value+"}";
return "\""+key+"\":"+value;
}
public static String parseEscapedString(String key, String value)
{
if(value==null)
......
package util;
public enum MgField
{
flowName,
unit,
ref,
kgbym3,
kgbym2,
refDensity,
rValueIn,
rValue,
refRValue,
thicknessMin,
thicknessMax,
indicator,
entityType,
skip;
}
\ No newline at end of file
package util;
import lombok.Getter;
import models.LCA.Middleground;
public class MiddleGroundTemplate
{
private final static int NOT_IN_TEMPLATE=-1;
private static FieldHandler[] lstFieldHandler;
private MgField[] template;
private int[] mapTemplate;
@Getter private String entityType;
public MiddleGroundTemplate(MgField[] template){this(template,null);}
public MiddleGroundTemplate(MgField[] template, String entityType)
{
initFieldHandler();
this.template=template;
this.mapTemplate = createReverseMap(this.template);
this.entityType = entityType;
}
public boolean setField(Middleground middleground, MgField field, Object[] values)
{
//Skip is always at NOT_IN_TEMPLATE
int ind=mapTemplate[field.ordinal()];
if(ind!=NOT_IN_TEMPLATE && values.length>ind)
return setField(middleground, field, values[ind]);
return false;
}
public boolean setAllField(Middleground middleground, Object[] values)
{
boolean succeed=true;
setEntityType(middleground);
for(MgField field:template)
{
succeed &= setField(middleground,field,values);
}
return succeed;
}
public void setEntityType(Middleground middleground)
{
if(entityType!=null)middleground.setEntityType(entityType);
}
public int getFieldOffset()
{
return this.template.length;
}
public Object getField(MgField field, Object[] values){ return getField(field,values,null); }
public Object getField(MgField field, Object[] values, Object defaultValue)
{
int indField = mapTemplate[field.ordinal()];
if(indField==NOT_IN_TEMPLATE || mapTemplate[field.ordinal()]>= values.length)
return defaultValue;
else
return values[field.ordinal()];
}
public Double getDoubleField(MgField field, Object[] values){ return getDoubleField(field,values,null); }
public Double getDoubleField(MgField field, Object[] values, Double defaultValue)
{
Object value = getField(field, values, defaultValue);
try
{
return value==null?null:Double.parseDouble(value.toString());
}
catch (NumberFormatException e) {}
return defaultValue;
}
public Integer getIntegerField(MgField field, Object[] values){ return getIntegerField(field, values,null); }
public Integer getIntegerField(MgField field, Object[] values, Integer defaultValue)
{
Object value = getField(field, values, defaultValue);
try
{
return value==null?null:Integer.parseInt(value.toString(),10);
}
catch (NumberFormatException e) {}
return defaultValue;
}
public String getStringField(MgField field, Object[] values){ return getStringField(field,values,null); }
public String getStringField(MgField field, Object[] values, String defaultValue)
{
Object value = getField(field, values, defaultValue);
if(value==null)
return null;
return value.toString();
}
public boolean contain(MgField field)
{
return mapTemplate[field.ordinal()]!=NOT_IN_TEMPLATE;
}
private boolean setField(Middleground middleground, MgField field, Object value)
{
return lstFieldHandler[field.ordinal()].setField(middleground,value);
}
private int[] createReverseMap(MgField[] template)
{
int[] mapTemplate = new int[MgField.values().length];
for(int i=0;i<mapTemplate.length;i++)
mapTemplate[i]=NOT_IN_TEMPLATE;
for(int i=0;i<template.length;i++)
{
if(template[i]!= MgField.skip)
{
mapTemplate[template[i].ordinal()]=i;
}
}
return mapTemplate;
}
private void initFieldHandler() {
if (lstFieldHandler == null)
{
lstFieldHandler = new FieldHandler[MgField.values().length];
lstFieldHandler[MgField.flowName.ordinal()] = new StringFieldHandler(){ @Override protected void setTypedField(Middleground middleground, String value) {}};
lstFieldHandler[MgField.unit.ordinal()] = new StringFieldHandler(){ @Override protected void setTypedField(Middleground middleground, String value) { middleground.setUnit(value); }};
lstFieldHandler[MgField.ref.ordinal()] = new StringFieldHandler(){ @Override protected void setTypedField(Middleground middleground, String value) { middleground.setRef(value); }};
lstFieldHandler[MgField.refDensity.ordinal()] = new StringFieldHandler(){ @Override protected void setTypedField(Middleground middleground, String value) { middleground.setRefDensity(value); }};
lstFieldHandler[MgField.refRValue.ordinal()] = new StringFieldHandler(){ @Override protected void setTypedField(Middleground middleground, String value) { middleground.setRefRValue(value); }};
lstFieldHandler[MgField.entityType.ordinal()] = new StringFieldHandler(){ @Override protected void setTypedField(Middleground middleground, String value) { middleground.setRefRValue(value); }};
lstFieldHandler[MgField.skip.ordinal()] = new StringFieldHandler(){ @Override protected void setTypedField(Middleground middleground, String value) {}};
lstFieldHandler[MgField.rValueIn.ordinal()] = new DoubleFieldHandler(){ @Override protected void setTypedField(Middleground middleground, Double value) {
middleground.setRValueIn(value);
}};
lstFieldHandler[MgField.rValue.ordinal()] = new DoubleFieldHandler(){ @Override protected void setTypedField(Middleground middleground, Double value) {
middleground.setRValue(value);
}};
lstFieldHandler[MgField.kgbym3.ordinal()] = new DoubleFieldHandler(){ @Override protected void setTypedField(Middleground middleground, Double value) { middleground.setKgbym3(value); }};
lstFieldHandler[MgField.kgbym2.ordinal()] = new DoubleFieldHandler(){ @Override protected void setTypedField(Middleground middleground, Double value) { middleground.setKgbym2(value); }};
lstFieldHandler[MgField.thicknessMin.ordinal()] = new DoubleFieldHandler(){ @Override protected void setTypedField(Middleground middleground, Double value) { middleground.setThicknessMin(value); }};
lstFieldHandler[MgField.thicknessMax.ordinal()] = new DoubleFieldHandler(){ @Override protected void setTypedField(Middleground middleground, Double value) { middleground.setThicknessMax(value); }};
lstFieldHandler[MgField.indicator.ordinal()] = new IntegerFieldHandler(){ @Override protected void setTypedField(Middleground middleground, Integer value) {
middleground.setIndicator(value);
}};
}
}
protected abstract class FieldHandler<T>
{
public abstract boolean setField(Middleground middleground, Object value);
protected abstract void setTypedField(Middleground middleground, T value);
}
protected abstract class StringFieldHandler extends FieldHandler<String>
{
@Override
public boolean setField(Middleground middleground, Object value)
{
setTypedField(middleground,value==null?null:value.toString());
return true;
}
}
protected abstract class DoubleFieldHandler extends FieldHandler<Double>
{