/********************************************************************** * This file is part of iDempiere ERP Open Source * * http://www.idempiere.org * * * * Copyright (C) Contributors * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation; either version 2 * * of the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * * MA 02110-1301, USA. * * * * Contributors: * * - Trek Global Corporation * * - Heng Sin Low * **********************************************************************/ package com.trekglobal.idempiere.rest.api.model; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Properties; import org.compiere.model.MColumn; import org.compiere.model.MTable; import org.compiere.model.PO; import org.compiere.model.Query; import org.compiere.util.Env; import org.idempiere.cache.ImmutableIntPOCache; import org.idempiere.cache.ImmutablePOCache; import org.idempiere.cache.ImmutablePOSupport; import com.trekglobal.idempiere.rest.api.json.TypeConverterUtils; public class MRestView extends X_REST_View implements ImmutablePOSupport { private static final long serialVersionUID = 7362614368992553892L; private final static ImmutablePOCache s_cache = new ImmutablePOCache(MRestView.Table_Name, 20); private final static ImmutableIntPOCache s_idCache = new ImmutableIntPOCache(MRestView.Table_Name, 20); private MRestViewColumn[] columns = null; private MRestViewRelated[] relateds = null; public MRestView(Properties ctx, int REST_View_ID, String trxName) { super(ctx, REST_View_ID, trxName); } public MRestView(Properties ctx, int REST_View_ID, String trxName, String... virtualColumns) { super(ctx, REST_View_ID, trxName, virtualColumns); } public MRestView(Properties ctx, String REST_View_UU, String trxName) { super(ctx, REST_View_UU, trxName); } public MRestView(Properties ctx, String REST_View_UU, String trxName, String... virtualColumns) { super(ctx, REST_View_UU, trxName, virtualColumns); } public MRestView(Properties ctx, ResultSet rs, String trxName) { super(ctx, rs, trxName); } public MRestView(MRestView copy) { this(Env.getCtx(), copy); } public MRestView(Properties ctx, MRestView copy) { this(ctx, copy, (String) null); } public MRestView(Properties ctx, MRestView copy, String trxName) { //-1 to avoid infinite loop this(ctx, -1, trxName); copyPO(copy); } @Override protected boolean afterSave(boolean newRecord, boolean success) { if (newRecord && success) { StackTraceElement[] stackTraces = Thread.currentThread().getStackTrace(); for (StackTraceElement stackTrace : stackTraces) { if ("org.adempiere.pipo2.PackIn".equals(stackTrace.getClassName())) { return true; } } copyColumns(); } else if (success) { if (is_ValueChanged(COLUMNNAME_AD_Table_ID)) { Query query = new Query(Env.getCtx(), MRestViewColumn.Table_Name, "REST_View_ID=?", null); List columnList = query.setParameters(getREST_View_ID()).list(); for(MRestViewColumn column : columnList) { column.deleteEx(true, get_TrxName()); } columns = null; copyColumns(); query = new Query(Env.getCtx(), MRestViewRelated.Table_Name, "REST_View_ID=?", null); List relatedList = query.setParameters(getREST_View_ID()).list(); for(MRestViewRelated related : relatedList) { related.deleteEx(true, get_TrxName()); } relateds = null; } } return success; } /** * Copy all columns from table */ private void copyColumns() { //auto populate view columns MTable table = MTable.get(getAD_Table_ID()); MColumn[] columns = table.getColumns(false); String keyColumn = table.getKeyColumns() != null && table.getKeyColumns().length == 1 ? table.getKeyColumns()[0] : ""; String uidColumn = PO.getUUIDColumnName(table.getTableName()); for(MColumn column : columns) { if (column.getColumnName().equals(keyColumn)) continue; else if (column.getColumnName().equals(uidColumn)) continue; MRestViewColumn restViewColumn = new MRestViewColumn(Env.getCtx(), 0, get_TrxName()); restViewColumn.setREST_View_ID(getREST_View_ID()); restViewColumn.setAD_Column_ID(column.getAD_Column_ID()); restViewColumn.setName(TypeConverterUtils.toPropertyName(column.getColumnName())); restViewColumn.saveEx(); } } /** * Get view by name * @param name * @return MRestView */ public static MRestView get(String name) { MRestView view = s_cache.get(Env.getCtx(), name, e -> new MRestView(Env.getCtx(), e)); if (view != null) return view; Query query = new Query(Env.getCtx(), Table_Name, "Name=?", null); view = query.setParameters(name).first(); if (view != null) { s_cache.put (name, view, e -> new MRestView(Env.getCtx(), e)); if (!s_idCache.containsKey(view.get_ID())) s_idCache.put(view.get_ID(), view, e -> new MRestView(Env.getCtx(), e)); } return view; } /** * Get view by id * @param name * @return MRestView */ public static MRestView get(int id) { MRestView view = s_idCache.get(Env.getCtx(), id, e -> new MRestView(Env.getCtx(), e)); if (view != null) return view; Query query = new Query(Env.getCtx(), Table_Name, "REST_View_ID=?", null); view = query.setParameters(id).first(); if (view != null) { s_idCache.put (id, view, e -> new MRestView(Env.getCtx(), e)); if (!s_cache.containsKey(view.getName())) s_cache.put(view.getName(), view, e -> new MRestView(Env.getCtx(), e)); } return view; } /** * Get view columns * @return view columns */ public MRestViewColumn[] getColumns() { return getColumns(false); } /** * Get view columns * @param refresh * @return view columns */ public MRestViewColumn[] getColumns(boolean refresh) { if (columns != null && !refresh) return columns; Query query = new Query(Env.getCtx(), MRestViewColumn.Table_Name, "REST_View_ID=?", null); List columnList = query.setOnlyActiveRecords(true) .setOrderBy("SeqNo, REST_ViewColumn_ID") .setParameters(getREST_View_ID()).list(); columns = columnList.toArray(new MRestViewColumn[0]); return columns; } /** * Get related detail views * @return related views */ public MRestViewRelated[] getRelatedViews() { return getRelatedViews(false); } /** * Get related detail views * @param refresh * @return related views */ public MRestViewRelated[] getRelatedViews(boolean refresh) { if (relateds != null && !refresh) return relateds; Query query = new Query(Env.getCtx(), MRestViewRelated.Table_Name, "REST_View_ID=?", null); List relatedList = query.setOnlyActiveRecords(true) .setParameters(getREST_View_ID()).list(); relateds = relatedList.toArray(new MRestViewRelated[0]); return relateds; } /** * Convert view property name to table column name * @param name * @return table column name or null */ public String toColumnName(String name) { MRestViewColumn[] columns = getColumns(); for(MRestViewColumn column : columns) { String columnName = MColumn.getColumnName(Env.getCtx(), column.getAD_Column_ID()); if (column.getName().equals(name)) { return columnName; } } return null; } /** * Convert list of view property name to table column names * @param includes * @param keepNotViewPropertyName true to keep input name in the return list when there's no matching view property name * @return list of names */ public String[] toColumnNames(String[] includes, boolean keepNotViewPropertyName) { List list = new ArrayList(); for(String include : includes) { String columnName = toColumnName(include); if (columnName != null) list.add(columnName); else if (keepNotViewPropertyName) list.add(include); } return list.toArray(new String[0]); } @Override public PO markImmutable() { if (is_Immutable()) return this; makeImmutable(); if (columns != null) { Arrays.stream(columns).forEach(e -> e.markImmutable()); } if (relateds != null) { Arrays.stream(relateds).forEach(e -> e.markImmutable()); } return this; } }