Java tutorial
/* * Copyright 2003 - 2016 The eFaps Team * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Revision: $Rev$ * Last Changed: $Date$ * Last Changed By: $Author$ */ package org.efaps.esjp.common.uiform; import java.io.IOException; import java.text.NumberFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.UUID; import org.apache.commons.lang3.StringUtils; import org.efaps.admin.datamodel.Attribute; import org.efaps.admin.datamodel.AttributeSet; import org.efaps.admin.datamodel.Classification; import org.efaps.admin.datamodel.Type; import org.efaps.admin.datamodel.attributetype.AbstractFileType; import org.efaps.admin.datamodel.attributetype.RateType; import org.efaps.admin.datamodel.ui.BitEnumUI; import org.efaps.admin.datamodel.ui.RateUI; import org.efaps.admin.event.EventDefinition; import org.efaps.admin.event.EventExecution; import org.efaps.admin.event.EventType; import org.efaps.admin.event.Parameter; import org.efaps.admin.event.Parameter.ParameterValues; import org.efaps.admin.event.Return; import org.efaps.admin.program.esjp.EFapsApplication; import org.efaps.admin.program.esjp.EFapsUUID; import org.efaps.admin.ui.AbstractCommand; import org.efaps.admin.ui.AbstractUserInterfaceObject.TargetMode; import org.efaps.admin.ui.Form; import org.efaps.admin.ui.field.Field; import org.efaps.admin.ui.field.FieldClassification; import org.efaps.admin.ui.field.FieldSet; import org.efaps.admin.ui.field.FieldTable; import org.efaps.db.Checkin; import org.efaps.db.Context; import org.efaps.db.Delete; import org.efaps.db.Insert; import org.efaps.db.Instance; import org.efaps.db.InstanceQuery; import org.efaps.db.MultiPrintQuery; import org.efaps.db.PrintQuery; import org.efaps.db.QueryBuilder; import org.efaps.db.Update; import org.efaps.esjp.common.AbstractCommon; import org.efaps.util.EFapsException; import org.efaps.util.cache.CacheReloadException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * TODO comment! * * @author The eFaps Team * @version $Id$ */ @EFapsUUID("3a99a177-8b5c-4dd4-b876-dcba28ea3138") @EFapsApplication("eFaps-Kernel") public abstract class Edit_Base extends AbstractCommon implements EventExecution { /** * Logging instance used in this class. */ protected static final Logger LOG = LoggerFactory.getLogger(Edit.class); /** * String used as a temp key. */ protected static final String FAKEROW = "NoMoreRowsExisting"; /** * @param _parameter Parameter as provided by eFaps for a esjp * @throws EFapsException on error * @return empty Return */ @Override public Return execute(final Parameter _parameter) throws EFapsException { final Instance instance = _parameter.getInstance(); final AbstractCommand command = (AbstractCommand) _parameter.get(ParameterValues.UIOBJECT); final Context context = Context.getThreadContext(); // update the Values for the general form final String classifcationName = updateMainElements(_parameter, command.getTargetForm(), instance); // ************************************ // check if we have a fileupload field if (context.getFileParameters().size() > 0) { for (final Field field : command.getTargetForm().getFields()) { final String attrName = field.getAttribute(); if (attrName == null && field.isEditableDisplay(TargetMode.EDIT)) { final Context.FileParameter fileItem = context.getFileParameters().get(field.getName()); if (fileItem != null) { final Checkin checkin = new Checkin(instance); try { checkin.execute(fileItem.getName(), fileItem.getInputStream(), (int) fileItem.getSize()); } catch (final IOException e) { throw new EFapsException(this.getClass(), "execute", e, _parameter); } } } } } if (classifcationName != null) { updateClassifcation(_parameter, instance, classifcationName); } updateConnection2Object(_parameter, instance); return new Return(); } /** * Method updates the main elements from the form. * * @param _parameter _parameter Parameter as provided by eFaps for a esjp * @param _form from used for the update * @param _instance instance that must be updated * @return the name of a classification if found in the form, else null * @throws EFapsException on error */ public String updateMainElements(final Parameter _parameter, final Form _form, final Instance _instance) throws EFapsException { return updateMainElements(_parameter, _form, _instance, new HashMap<String, Object>(), null); } /** * Method updates the main elements from the form. * * @param _parameter _parameter Parameter as provided by eFaps for a esjp * @param _form from used for the update * @param _instance instance that must be updated * @param _valueMap map of values * @param _fieldTables list of tables * @return the name of a classification if found in the form, else null * @throws EFapsException on error */ public String updateMainElements(final Parameter _parameter, final Form _form, final Instance _instance, final Map<String, Object> _valueMap, final List<FieldTable> _fieldTables) throws EFapsException { String ret = null; final List<FieldSet> fieldsets = new ArrayList<FieldSet>(); final List<FieldTable> fieldTables; if (_fieldTables == null) { fieldTables = new ArrayList<FieldTable>(); } else { fieldTables = _fieldTables; } final List<Field> fields = new ArrayList<Field>(); final PrintQuery print = new PrintQuery(_instance); for (final Field field : _form.getFields()) { if (field instanceof FieldSet) { fieldsets.add((FieldSet) field); } else if (field instanceof FieldTable && field.isEditableDisplay(TargetMode.EDIT)) { fieldTables.add((FieldTable) field); } else if (field instanceof FieldClassification) { ret = ((FieldClassification) field).getClassificationName(); } else { final String attrName = field.getAttribute(); if (attrName != null && field.isEditableDisplay(TargetMode.EDIT)) { final Attribute attr = _instance.getType().getAttribute(attrName); // check if not a fileupload if (attr != null && !AbstractFileType.class.isAssignableFrom(attr.getAttributeType().getClassRepr())) { print.addAttribute(attrName); fields.add(field); } } } } final Context context = Context.getThreadContext(); if (print.execute()) { final Update update = new Update(_instance); for (final Field field : fields) { final String attrName = field.getAttribute(); final Attribute attr = _instance.getType().getAttribute(attrName); if (attr != null && (context.getParameters().containsKey(field.getName()) || attr.getAttributeType().getUIProvider() instanceof BitEnumUI)) { final String[] newValue = _parameter.getParameterValues(field.getName()); final Object object = print.getAttribute(attrName); final String oldValue = object != null ? object.toString() : null; if (newValue == null && oldValue != null || newValue != null && !newValue.equals(oldValue)) { _valueMap.put(attrName, add2Update(_parameter, update, attr, field.getName())); } } } add2MainUpdate(_parameter, update); update.execute(); } updateFieldSets(_parameter, _instance, fieldsets); if (_fieldTables == null) { updateFieldTable(_parameter, _instance, fieldTables); } return ret; } /** * @param _parameter Parameter as passed by the eFaps API * @param _update Update * @throws EFapsException on error */ protected void add2MainUpdate(final Parameter _parameter, final Update _update) throws EFapsException { // to be used form implementations } /** * Add to the given update. * @param _parameter Parameter as passed by the eFaps API * @param _update Update * @param _attr Attribute * @param _fieldName name of the Field * @throws EFapsException on error * @return the object addeded */ protected Object add2Update(final Parameter _parameter, final Update _update, final Attribute _attr, final String _fieldName) throws EFapsException { final Context context = Context.getThreadContext(); Object ret = null; if (_attr.hasUoM()) { final Object[] tmp = new Object[] { _parameter.getParameterValue(_fieldName), _parameter.getParameterValue(_fieldName + "UoM") }; _update.add(_attr, tmp); ret = tmp; } else if (_attr.getAttributeType().getDbAttrType() instanceof RateType) { final String value = _parameter.getParameterValue(_fieldName); final boolean inverted = "true" .equalsIgnoreCase(context.getParameter(_fieldName + RateUI.INVERTEDSUFFIX)); final Object[] tmp = new Object[] { inverted ? 1 : value, inverted ? value : 1 }; _update.add(_attr, tmp); ret = tmp; } else if (_attr.getAttributeType().getUIProvider() instanceof BitEnumUI) { final String[] tmp = _parameter.getParameterValues(_fieldName); if (tmp == null) { _update.add(_attr, (Object[]) null); } else { _update.add(_attr, Arrays.copyOf(tmp, tmp.length, Object[].class)); } ret = tmp; } else { ret = _parameter.getParameterValue(_fieldName); _update.add(_attr, ret); } return ret; } /** * @param _parameter Parameter as passed by the eFaps API * @param _update Update to add to * @param _attr current Attribute * @param _fieldName name of the field * @param _idx index * @throws EFapsException obn error */ protected void add2Update(final Parameter _parameter, final Update _update, final Attribute _attr, final String _fieldName, final int _idx) throws EFapsException { if (_attr.hasUoM()) { _update.add(_attr, new Object[] { _parameter.getParameterValues(_fieldName)[_idx], _parameter.getParameterValues(_fieldName + "UoM")[_idx] }); } else if (_attr.getAttributeType().getDbAttrType() instanceof RateType) { final String value = _parameter.getParameterValues(_fieldName)[_idx]; final boolean inverted = "true" .equalsIgnoreCase(_parameter.getParameterValues(_fieldName + RateUI.INVERTEDSUFFIX)[_idx]); _update.add(_attr, new Object[] { inverted ? 1 : value, inverted ? value : 1 }); } else { _update.add(_attr, _parameter.getParameterValues(_fieldName)[_idx]); } } // OLD VERSION! WILL BE REMOVED private void updateFieldSetsOld(final Parameter _parameter, final Instance _instance, final List<FieldSet> _fieldsets) throws EFapsException { final NumberFormat nf = NumberFormat.getInstance(); nf.setMinimumIntegerDigits(2); nf.setMaximumIntegerDigits(2); for (final FieldSet fieldset : _fieldsets) { final String setName = fieldset.getAttribute(); final AttributeSet set = AttributeSet.find(_instance.getType().getName(), setName); // first already existing values must be updated, if they were // altered boolean updateExisting = true; int yCoord = 0; while (updateExisting) { // check in the context if already existing values might have // been altered, by // using the hidden field that is added when existing values for // a fieldset are shown final String idfield = "hiddenId_" + fieldset.getName() + "_" + nf.format(yCoord); if (_parameter.getParameters().containsKey(idfield)) { final String id = _parameter.getParameterValue(idfield); // check the values in the database final PrintQuery printQuery = new PrintQuery(set, id); for (final Attribute attr : set.getAttributes().values()) { printQuery.addAttribute(attr); } printQuery.execute(); final Update setupdate = new Update(set, id); int xCoord = 0; boolean update = false; for (final String attrName : fieldset.getOrder()) { final Attribute child = set.getAttribute(attrName); final String fieldName = fieldset.getName() + "_" + nf.format(yCoord) + nf.format(xCoord); if (_parameter.getParameters().containsKey(fieldName)) { final Object object = printQuery.getAttribute(attrName); final String oldValue = object != null ? object.toString() : null; final String newValue = _parameter.getParameterValue(fieldName); if (!newValue.equals(oldValue)) { add2Update(_parameter, setupdate, child, fieldName); update = true; } } xCoord++; } if (update) { setupdate.execute(); } } else { updateExisting = false; } yCoord++; } // add new values final Map<?, ?> others = (HashMap<?, ?>) _parameter.get(ParameterValues.OTHERS); if (others != null) { // add new Values final String[] yCoords = (String[]) others.get(fieldset.getName() + "_eFapsNew"); if (yCoords != null) { for (final String ayCoord : yCoords) { final Insert insert = new Insert(set); insert.add(set.getAttribute(setName), ((Long) _instance.getId()).toString()); int xCoord = 0; for (final String attrName : fieldset.getOrder()) { final Attribute child = set.getAttribute(attrName); final String fieldName = fieldset.getName() + "_eFapsNew_" + nf.format(Integer.parseInt(ayCoord)) + nf.format(xCoord); if (_parameter.getParameters().containsKey(fieldName)) { add2Update(_parameter, insert, child, fieldName); } xCoord++; } insert.execute(); } } // remove deleted Values final String[] removeOnes = (String[]) others.get(fieldset.getName() + "eFapsRemove"); if (removeOnes != null) { for (final String removeOne : removeOnes) { final Delete delete = new Delete(set, removeOne); delete.execute(); } } } } } /** * Method to update the related fieldsets if parameters are given for them. * * @param _parameter Parameter as passed from the efaps API. * @param _instance Instance of the new object * @param _fieldsets fieldsets to insert * @throws EFapsException on error */ public void updateFieldSets(final Parameter _parameter, final Instance _instance, final List<FieldSet> _fieldsets) throws EFapsException { @SuppressWarnings("unchecked") final Map<String, String> idmap = (Map<String, String>) _parameter.get(ParameterValues.OIDMAP4UI); for (final FieldSet fieldset : _fieldsets) { if (_parameter.getParameters().containsKey(fieldset.getName() + "eFapsRemove")) { // to mantain backward compatibility updateFieldSetsOld(_parameter, _instance, _fieldsets); break; } else { final String setName = fieldset.getAttribute(); final AttributeSet set = AttributeSet.find(_instance.getType().getName(), setName); Object[] ids = null; if (_parameter.getParameters().containsKey(fieldset.getName() + "_ID")) { final String[] idArray = _parameter.getParameterValues(fieldset.getName() + "_ID"); ids = new Object[idArray.length]; for (int i = 0; i < idArray.length; i++) { final String oid = idmap.get(idArray[i]); // in case of new Update update; if (oid == null) { update = new Insert(set); update.add(set.getAttribute(setName), _instance.getId()); } else { update = new Update(oid); } for (final String attrName : fieldset.getOrder()) { final Attribute child = set.getAttribute(attrName); final String fieldName = fieldset.getName() + "_" + attrName; if (_parameter.getParameters().containsKey(fieldName)) { add2Update(_parameter, update, child, fieldName, i); } } update.execute(); ids[i] = update.getId(); } } final QueryBuilder queryBldr = new QueryBuilder(set); queryBldr.addWhereAttrEqValue(set.getAttribute(setName), _instance.getId()); if (ids != null) { queryBldr.addWhereAttrNotEqValue("ID", ids); } final InstanceQuery query = queryBldr.getQuery(); for (final Instance toDelInst : query.execute()) { final Delete del = new Delete(toDelInst); del.execute(); } } } } /** * Method to update the classifications. * * @param _parameter Parameter as passed from the efaps API. * @param _instance Instance of the new object * @param _classifcationName name of the classificationto be updated * @throws EFapsException on error */ public void updateClassifcation(final Parameter _parameter, final Instance _instance, final String _classifcationName) throws EFapsException { final List<?> classifications = (List<?>) _parameter.get(ParameterValues.CLASSIFICATIONS); final Classification classType = (Classification) Type.get(_classifcationName.split(";")[0]); final Map<Classification, Map<String, Object>> clas2values = new HashMap<Classification, Map<String, Object>>(); // get the already existing classifications final QueryBuilder relQueryBldr = new QueryBuilder(classType.getClassifyRelationType()); relQueryBldr.addWhereAttrEqValue(classType.getRelLinkAttributeName(), _instance.getId()); final MultiPrintQuery relMulti = relQueryBldr.getPrint(); relMulti.addAttribute(classType.getRelTypeAttributeName()); relMulti.execute(); while (relMulti.next()) { final Long typeid = relMulti.<Long>getAttribute(classType.getRelTypeAttributeName()); final Classification subClassType = (Classification) Type.get(typeid); final Map<String, Object> values = new HashMap<String, Object>(); clas2values.put(subClassType, values); final QueryBuilder subQueryBldr = new QueryBuilder(subClassType); subQueryBldr.addWhereAttrEqValue(subClassType.getLinkAttributeName(), _instance.getId()); final MultiPrintQuery subMulti = subQueryBldr.getPrint(); final List<Field> fields = new ArrayList<Field>(); final Form form = Form.getTypeForm(subClassType); for (final Field field : form.getFields()) { final String attrName = field.getAttribute(); if (attrName != null && field.isEditableDisplay(TargetMode.EDIT)) { final Attribute attr = subClassType.getAttribute(attrName); // check if not a fileupload if (attr != null && !AbstractFileType.class.isAssignableFrom(attr.getAttributeType().getClassRepr())) { subMulti.addAttribute(attrName); fields.add(field); } } } if (subMulti.execute()) { if (subMulti.next()) { for (final Field field : fields) { final String attrName = field.getAttribute(); values.put(field.getName(), subMulti.getAttribute(attrName)); } values.put("OID", subMulti.getCurrentInstance().getOid()); } } values.put("relOID", relMulti.getCurrentInstance().getOid()); } if (classifications != null) { for (final Object object : classifications) { final Classification classification = (Classification) object; // if the classification does not exist yet the relation must be // created, and the new instance of the classification inserted final Form form = Form.getTypeForm(classification); if (!clas2values.containsKey(classification)) { final Insert relInsert = new Insert(classification.getClassifyRelationType()); relInsert.add(classification.getRelLinkAttributeName(), ((Long) _instance.getId()).toString()); relInsert.add(classification.getRelTypeAttributeName(), ((Long) classification.getId()).toString()); relInsert.execute(); final Insert classInsert = new Insert(classification); classInsert.add(classification.getLinkAttributeName(), ((Long) _instance.getId()).toString()); final List<FieldSet> fieldsets = new ArrayList<FieldSet>(); new HashSet<>(); for (final Field field : form.getFields()) { if (field instanceof FieldSet) { fieldsets.add((FieldSet) field); } else { final String attrName = field.getAttribute(); if (attrName != null && (field.isEditableDisplay(TargetMode.EDIT) || field.isEditableDisplay(TargetMode.CREATE))) { final Attribute attr = classification.getAttribute(attrName); if (attr != null && _parameter.getParameterValue(field.getName()) != null && !AbstractFileType.class .isAssignableFrom(attr.getAttributeType().getClassRepr())) { add2Update(_parameter, classInsert, attr, field.getName()); } } } } classInsert.execute(); updateFieldSets(_parameter, classInsert.getInstance(), fieldsets); } else { final Map<String, Object> values = clas2values.get(classification); final List<FieldSet> fieldsets = new ArrayList<FieldSet>(); final Update update = new Update((String) values.get("OID")); boolean execUpdate = false; for (final Field field : form.getFields()) { if (field instanceof FieldSet) { fieldsets.add((FieldSet) field); } else { final String attrName = field.getAttribute(); if (attrName != null && (field.isEditableDisplay(TargetMode.EDIT) || field.isEditableDisplay(TargetMode.CREATE))) { final Attribute attr = classification.getAttribute(attrName); if (attr != null && _parameter.getParameterValue(field.getName()) != null && !AbstractFileType.class .isAssignableFrom(attr.getAttributeType().getClassRepr())) { if (_parameter.getParameters().containsKey(field.getName()) || attr.getAttributeType().getUIProvider() instanceof BitEnumUI) { final String newValue = _parameter.getParameterValue(field.getName()); final Object value = values.get(field.getName()); final String oldValue = value != null ? value.toString() : null; if (newValue == null && oldValue != null || newValue != null && !newValue.equals(oldValue)) { execUpdate = true; add2Update(_parameter, update, attr, field.getName()); } } } } } } if (execUpdate) { update.execute(); } updateFieldSets(_parameter, update.getInstance(), fieldsets); } } } // remove the classifications that are not any more wanted for (final Classification clas : clas2values.keySet()) { if (classifications == null || !classifications.contains(clas)) { final Instance delInst = Instance.get((String) clas2values.get(clas).get("OID")); if (delInst.isValid()) { final Delete del = new Delete(delInst); del.execute(); } final Instance relDelInst = Instance.get((String) clas2values.get(clas).get("relOID")); if (relDelInst.isValid()) { final Delete del = new Delete(relDelInst); del.execute(); } } } } /** * Method to update the fieldtables. * * @param _parameter Parameter as passed from the eFaps API * @param _instance instance * @param _fieldTables list of fieldtables * @throws EFapsException on error */ public void updateFieldTable(final Parameter _parameter, final Instance _instance, final List<FieldTable> _fieldTables) throws EFapsException { if (_fieldTables.size() > 0) { final List<RowUpdate> rows = analyseFieldTables(_parameter, _fieldTables); deleteRows(_parameter, rows); updateAddRows(_parameter, rows); } } /** * Delete removed rows. * * @param _parameter Parameter as passed from the eFaps API * @param _rows rows to be updated or added * @throws EFapsException on error */ public void deleteRows(final Parameter _parameter, final List<RowUpdate> _rows) throws EFapsException { final Map<?, ?> oids = (Map<?, ?>) _parameter.get(ParameterValues.OIDMAP4UI); final Map<Type, Set<String>> exist = new HashMap<Type, Set<String>>(); final Map<Type, String> type2LinkAttr = new HashMap<Type, String>(); for (final RowUpdate row : _rows) { if (oids.containsKey(row.getRowId())) { Set<String> set; if (exist.containsKey(row.getType())) { set = exist.get(row.getType()); } else { set = new HashSet<String>(); exist.put(row.getType(), set); type2LinkAttr.put(row.getType(), row.getLinkAttrName()); } set.add((String) oids.get(row.getRowId())); } } for (final Entry<Type, Set<String>> entry : exist.entrySet()) { final QueryBuilder queryBldr = new QueryBuilder(entry.getKey()); queryBldr.addWhereAttrEqValue(type2LinkAttr.get(entry.getKey()), _parameter.getInstance().getId()); final InstanceQuery query = queryBldr.getQuery(); query.execute(); while (query.next()) { final String oid = query.getCurrentValue().getOid(); if (!entry.getValue().contains(oid)) { final Delete del = new Delete(oid); del.execute(); } } } } /** * Update and add new Rows. * * @param _parameter Parameter as passed from the eFaps API * @param _rows rows to be updated or added * @throws EFapsException on error */ public void updateAddRows(final Parameter _parameter, final List<RowUpdate> _rows) throws EFapsException { // TODO compare with database before update?? final Map<?, ?> oids = (Map<?, ?>) _parameter.get(ParameterValues.OIDMAP4UI); for (final RowUpdate row : _rows) { if (!Edit_Base.FAKEROW.equals(row.getRowId())) { final String oid = (String) oids.get(row.getRowId()); final Update update; if (oid != null) { update = new Update(oid); } else { update = new Insert(row.getType()); update.add(row.getLinkAttrName(), _parameter.getInstance().getId()); } for (final Entry<String, Object> entry : row.getValues().entrySet()) { update.add(entry.getKey(), entry.getValue()); } add2Update4FieldTable(_parameter, update, row); update.execute(); } } } /** * Add additionals to the Update. * * @param _parameter Parameter as passed by the eFaps API * @param _update Updaet that will be executed * @param _row row info * @throws EFapsException on error */ protected void add2Update4FieldTable(final Parameter _parameter, final Update _update, final RowUpdate _row) throws EFapsException { // to be implemented by subclasses. } /** * Analyze the table values row by row. * * @param _parameter Parameter as passed fromthe eFaps API * @param _fieldTables list of fieldtables * @return list of rows * @throws CacheReloadException on error */ public List<RowUpdate> analyseFieldTables(final Parameter _parameter, final List<FieldTable> _fieldTables) throws CacheReloadException { final List<RowUpdate> rows = new ArrayList<RowUpdate>(); boolean deleteAll = false; if (_parameter.getParameterValues("eFapsTRID") == null) { deleteAll = true; } else { // get all rows for (final String rowId : _parameter.getParameterValues("eFapsTRID")) { rows.add(new RowUpdate(rowId)); } } final Iterator<RowUpdate> rowiter = rows.iterator(); for (final FieldTable fieldTable : _fieldTables) { if (fieldTable.isEditableDisplay(TargetMode.EDIT)) { // get the type of the table object final List<EventDefinition> events = fieldTable.getEvents(EventType.UI_TABLE_EVALUATE); if (events.size() > 0) { final EventDefinition event = events.get(0); final Type type; final String conattr; if (event.getProperty("Expand") != null) { // TODO remove! Edit_Base.LOG.error("Use of deprecated api calling for Field: '%s' in Collection '%s' ", new Object[] { fieldTable.getName(), fieldTable.getCollection().getName() }); final String expand = event.getProperty("Expand"); final String[] typeatt = expand.split("\\\\"); final String typeStr = typeatt[0]; type = Type.get(typeStr); conattr = typeatt[1]; } else { if (event.getProperty("Types") != null) { Edit_Base.LOG.error("Use of deprecated api calling for Field: '%s' in Collection '%s' ", new Object[] { fieldTable.getName(), fieldTable.getCollection().getName() }); type = Type.get(event.getProperty("Types")); conattr = event.getProperty("LinkFroms"); } else { type = Type.get(event.getProperty("Type")); conattr = event.getProperty("LinkFrom"); } } if (deleteAll) { final RowUpdate fake = new RowUpdate(Edit_Base.FAKEROW); fake.setType(type); fake.setLinkAttrName(conattr); rows.add(fake); } else { int i = 0; boolean more = true; boolean first = true; while (more && rowiter.hasNext()) { RowUpdate row = null; if (!first) { row = rowiter.next(); row.setIndex(i); row.setType(type); row.setLinkAttrName(conattr); } for (final Field field : fieldTable.getTargetTable().getFields()) { final String attrName = field.getAttribute(); if (attrName != null && field.isEditableDisplay(TargetMode.EDIT)) { final String[] values = _parameter.getParameterValues(field.getName()); if (values != null && values.length > i) { if (first) { row = rowiter.next(); row.setIndex(i); row.setType(type); row.setLinkAttrName(conattr); first = false; } row.addValue(_parameter, attrName, field.getName(), i); } else { more = false; break; } } } i++; } } } } } return rows; } /** * Update connection 2 object. * * @param _parameter the _parameter * @param _instance the instance * @throws EFapsException on error */ public void updateConnection2Object(final Parameter _parameter, final Instance _instance) throws EFapsException { final Map<Integer, String> connectTypes = analyseProperty(_parameter, "ConnectType"); if (!connectTypes.isEmpty()) { final Map<Integer, String> currentLinks = analyseProperty(_parameter, "ConnectCurrentLink"); final Map<Integer, String> foreignLinks = analyseProperty(_parameter, "ConnectForeignLink"); final Map<Integer, String> foreignFields = analyseProperty(_parameter, "ConnectForeignField"); // all must be of the same size if (connectTypes.size() == currentLinks.size() && foreignLinks.size() == foreignFields.size() && connectTypes.size() == foreignLinks.size()) { for (final Entry<Integer, String> entry : connectTypes.entrySet()) { final String[] foreigns = _parameter.getParameterValues(foreignFields.get(entry.getKey())); if (foreigns != null) { for (final String foreign : foreigns) { final String typeStr = entry.getValue(); final Type type = isUUID(typeStr) ? Type.get(UUID.fromString(typeStr)) : Type.get(typeStr); final QueryBuilder queryBldr = new QueryBuilder(type); queryBldr.addWhereAttrEqValue(currentLinks.get(entry.getKey()), _instance); final List<Instance> insts = queryBldr.getQuery().execute(); if (insts.size() == 1 && StringUtils.isEmpty(foreign)) { new Delete(insts.get(0)).execute(); } else if (insts.size() < 2 && !StringUtils.isEmpty(foreign)) { final Update update = insts.isEmpty() ? new Insert(type) : new Update(insts.get(0)); if (insts.isEmpty()) { update.add(currentLinks.get(entry.getKey()), _instance); } final Instance inst = Instance.get(foreign); if (inst.isValid()) { update.add(foreignLinks.get(entry.getKey()), inst); } else { update.add(foreignLinks.get(entry.getKey()), foreign); } add2updateConnection2Object(_parameter, update); update.execute(); } } } } } else { Edit_Base.LOG.error("The properties must be of the same size!"); } } } /** * Add2update connection2 object. * * @param _parameter the _parameter * @param _update the _update * @throws EFapsException on error */ protected void add2updateConnection2Object(final Parameter _parameter, final Update _update) throws EFapsException { } /** * Class for update of a row. */ public static class RowUpdate { /** * Id of this row. */ private final String rowId; /** * index of this row. */ private int index; /** * Type for this row. */ private Type type; /** * Values in this row. */ private final Map<String, Object> values = new HashMap<String, Object>(); /** * Name of the link attribute. */ private String linkAttrName; /** * @param _rowId id of the row */ public RowUpdate(final String _rowId) { this.rowId = _rowId; } /** * Getter method for the instance variable {@link #rowId}. * * @return value of instance variable {@link #rowId} */ public String getRowId() { return this.rowId; } /** * Getter method for the instance variable {@link #index}. * * @return value of instance variable {@link #index} */ public int getIndex() { return this.index; } /** * Getter method for the instance variable {@link #type}. * * @return value of instance variable {@link #type} */ public Type getType() { return this.type; } /** * Getter method for the instance variable {@link #values}. * * @return value of instance variable {@link #values} */ public Map<String, Object> getValues() { return this.values; } /** * Adds the value. * * @param _parameter Parameter as passed by the eFaps API * @param _attrName name of the attribute * @param _fieldName the field name * @param _idx the idx */ public void addValue(final Parameter _parameter, final String _attrName, final String _fieldName, final int _idx) { final Attribute attribute = getType().getAttribute(_attrName); if (attribute != null) { final Object value; if (attribute.hasUoM()) { value = new Object[] { _parameter.getParameterValues(_fieldName)[_idx], _parameter.getParameterValues(_fieldName + "UoM")[_idx] }; } else if (attribute.getAttributeType().getDbAttrType() instanceof RateType) { final String valueTmp = _parameter.getParameterValues(_fieldName)[_idx]; final boolean inverted = "true".equalsIgnoreCase( _parameter.getParameterValues(_fieldName + RateUI.INVERTEDSUFFIX)[_idx]); value = new Object[] { inverted ? 1 : valueTmp, inverted ? valueTmp : 1 }; } else if (attribute.hasLink()) { final String valueTmp = _parameter.getParameterValues(_fieldName)[_idx]; final Instance inst = Instance.get(valueTmp); if (inst.isValid()) { value = inst; } else { value = valueTmp; } } else { value = _parameter.getParameterValues(_fieldName)[_idx]; } this.values.put(_attrName, value); } } /** * Setter method for instance variable {@link #type}. * * @param _type value for instance variable {@link #type} */ public void setType(final Type _type) { this.type = _type; } /** * Setter method for instance variable {@link #index}. * * @param _index value for instance variable {@link #index} */ public void setIndex(final int _index) { this.index = _index; } /** * Getter method for the instance variable {@link #linkAttrName}. * * @return value of instance variable {@link #linkAttrName} */ public String getLinkAttrName() { return this.linkAttrName; } /** * Setter method for instance variable {@link #linkAttrName}. * * @param _linkAttrName value for instance variable * {@link #linkAttrName} */ public void setLinkAttrName(final String _linkAttrName) { this.linkAttrName = _linkAttrName; } } }