All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.viaoa.hub.HubGroupBy Maven / Gradle / Ivy

The newest version!
/*  Copyright 1999 Vince Via [email protected]
    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.
*/
package com.viaoa.hub;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;

import com.viaoa.object.OAGroupBy;
import com.viaoa.object.OALinkInfo;
import com.viaoa.object.OAObject;
import com.viaoa.object.OAObjectInfo;
import com.viaoa.object.OAObjectInfoDelegate;
import com.viaoa.object.OASiblingHelper;
import com.viaoa.object.OAThreadLocalDelegate;
import com.viaoa.util.OAPropertyPath;
import com.viaoa.util.OAString;

/*
 * Creates a groupBy hub using a new single hub and property path.
 * 
* Equivalent of a database groupBy. * The combined Hub (see getCombinedHub) uses OAObject OAGroupBy, * where G is the same class as the groupBy Hub and F is a hub of the from objects. * * // group Employees by Dept new * HubGroupBy(hubEmp, hubAllDept, "depts") = new HubGroupBy(hubEmp, "depts") * * Split property path - this is when all of the methods in a pp are not public (link that does not create method). * * HubGroupBy is able to group them by splitting the pp using HubGroupBy and HubFrom to get a combined group. * ex: MRADClient.Application.ApplicationType.ApplicationGroup, hubFrom=hubMRADClients, hubGroupBy=hubApplicationGroups * * note: the method for ApplicationType.getApplicationGroups() is not created * * new HubGroupBy(hubMRADClients, hubApplicationGroups, "MRADClient.Application.ApplicationType.ApplicationGroup") * internally will create 2 HubGroupBys ... (hubMRADClients, "MRADClient.Application.ApplicationType") (hubApplicationGroups, "ApplicationTypes") * * @see HubLeftJoin to create a "flat" list of the grouping object (ex: Dept) * * @author vvia */ public class HubGroupBy { // from hub that are to be grouped private Hub hubFrom; private final Class classFrom; private Class classGroupBy; // optional hub to use as groupBy list. Required if the propertyPath has a "split/gap" (method does not exist) private Hub hubGroupBy; // result hub private Hub> hubCombined; private String propertyPath; // optional name of Hub property in groupBy object private String hubPropertyName; // internal calc prop created (if needed) private String listenPropertyName; private Hub hubMaster; private Hub hubDetail; private boolean bIgnoreAOChange; private boolean bCreateNullList; // used to name internally created calcProps private final static AtomicInteger aiCnt = new AtomicInteger(); /** * Create a hub of objects that are based on hubB. * * @param hubB from hub * @param propertyPath to groupBy link property */ public HubGroupBy(Hub hubB, String propertyPath, boolean bCreateNullList) { this.hubGroupBy = null; this.hubFrom = hubB; this.classFrom = hubB.getObjectClass(); this.classGroupBy = null; this.propertyPath = propertyPath; this.bCreateNullList = bCreateNullList; setup(); } public HubGroupBy(Hub hubB, String propertyPath) { this(hubB, propertyPath, true); } /** * @param hubB from hub to use as the root. * @param propertyPath to the groupBy property * @param hubPropertyName hub method for linkMany w/ type=groupBy */ public HubGroupBy(Hub hubB, String propertyPath, String hubPropertyName) { this.hubGroupBy = null; this.hubFrom = hubB; this.classFrom = hubB.getObjectClass(); this.classGroupBy = null; this.propertyPath = propertyPath; this.hubPropertyName = hubPropertyName; this.bCreateNullList = false; setup(); } /** * Create a hub on objects that are based on fromHub, and are grouped by hubGrpBy. This allows the combined hub to have a full list like * a left-join. * * @param propertyPath pp of the property from hubFrom to hubB. */ public HubGroupBy(Hub hubFrom, Hub hubGrpBy, String propertyPath, boolean bCreateNullList) { this.hubFrom = hubFrom; this.hubGroupBy = hubGrpBy; this.classFrom = hubFrom.getObjectClass(); this.classGroupBy = null; this.propertyPath = propertyPath; this.bCreateNullList = bCreateNullList; setup(); } public HubGroupBy(Hub hubFrom, Hub hubGrpBy, String propertyPath) { this(hubFrom, hubGrpBy, propertyPath, true); } /** * Combine two hgbs. */ public HubGroupBy(HubGroupBy hgb1, HubGroupBy hgb2, boolean bCreateNullList) { if (hgb1 == null || hgb2 == null) { throw new IllegalArgumentException("hgb1 & hgb2 can not be null"); } this.bCreateNullList = bCreateNullList; this.classFrom = hgb1.classFrom; this.classGroupBy = hgb1.classGroupBy; setupCombined(hgb1, hgb2); } public HubGroupBy(HubGroupBy hgb1, HubGroupBy hgb2) { this(hgb1, hgb2, true); } /** * create a new hgb that creates a combined groupBy with another. */ public HubGroupBy(HubGroupBy hgb, String pp, boolean bCreateNullList) { if (hgb == null) { throw new IllegalArgumentException("hgb can not be null"); } this.classFrom = hgb.classFrom; this.classGroupBy = null; this.bCreateNullList = bCreateNullList; HubGroupBy hgb2 = new HubGroupBy(hgb.hubFrom, pp, bCreateNullList); setupCombined(hgb, hgb2); } public HubGroupBy(HubGroupBy hgb, String pp) { this(hgb, pp, true); } /** * @return Hub of combined objects using OAGroupBy */ public Hub> getCombinedHub() { if (hubCombined != null) { return hubCombined; } hubCombined = new Hub(OAGroupBy.class); return hubCombined; } /** * @return Hub of groupBy objects that are in sync (share AO) with combined Hub. */ public Hub getMasterHub() { if (hubMaster == null) { if (hubGroupBy != null) { hubMaster = new Hub(hubGroupBy.getObjectClass()); } else { hubMaster = new Hub(); } new HubMerger(getCombinedHub(), hubMaster, OAGroupBy.P_GroupBy, true); hubMaster.addHubListener(new HubListenerAdapter() { @Override public void afterChangeActiveObject(HubEvent e) { if (bIgnoreAOChange) { return; } try { bIgnoreAOChange = true; final Object ao = e.getObject(); hubFrom.setAO(null); if (hubDetail != null) { hubDetail.setAO(null); } if (ao == null) { getCombinedHub().setAO(null); } else { boolean bFound = false; for (OAGroupBy bg : getCombinedHub()) { if (bg.getGroupBy() == ao) { getCombinedHub().setAO(bg); bFound = true; break; } } if (!bFound) { getCombinedHub().setAO(null); } } } finally { bIgnoreAOChange = false; } } @Override public void afterAdd(HubEvent e) { if (classGroupBy == null) { classGroupBy = (Class) e.getObject().getClass(); } } }); } return hubMaster; } /** * @return detail hub from compoundHub.hub */ public Hub getDetailHub() { if (hubDetail == null) { String pp = "(" + classFrom.getName() + ") " + OAGroupBy.P_Hub; hubDetail = getCombinedHub().getDetailHub(pp); HubDelegate.setObjectClass(hubDetail, classFrom); hubDetail.addHubListener(new HubListenerAdapter() { @Override public void afterChangeActiveObject(HubEvent e) { if (bIgnoreAOChange) { return; } try { bIgnoreAOChange = true; hubFrom.setAO(e.getObject()); } finally { bIgnoreAOChange = false; } } }); } return hubDetail; } void setup() { OAPropertyPath opp = new OAPropertyPath(propertyPath); try { opp.setup(classFrom, (hubGroupBy != null)); } catch (Exception e) { throw new RuntimeException("PropertyPath setup failed", e); } OALinkInfo[] lis = opp.getLinkInfos(); Method[] ms = opp.getMethods(); int posEmpty = 0; for (Method m : ms) { if (m == null) { break; } posEmpty++; } if (posEmpty >= ms.length || hubGroupBy == null) { setupMain(); return; // does not need to be split } // need to have a 2way propPath, one from rootHub, and another from topDown hub String pp1 = OAString.field(propertyPath, ".", 1, posEmpty); String pp2 = ""; for (int i = ms.length - 1; i >= posEmpty; i--) { if (pp2.length() > 0) { pp2 += "."; } pp2 += lis[i].getReverseName(); } hgb1 = new HubGroupBy(hubFrom, pp1, bCreateNullList); hubGB1 = hgb1.getCombinedHub(); hgb2 = new HubGroupBy(hubGroupBy, pp2, bCreateNullList); hubGB2 = hgb2.getCombinedHub(); setupSplit(); } // used by propertyPath that require a split private HubGroupBy hgb1; private Hub hubGB1; private HubGroupBy hgb2; private Hub hubGB2; /* This is used to define the structure that is created for the split. *


	    Original HubGroupBy  new HubGroupBy(hubApplicationGroup, hubMRADClient, "MRADClient.Application.ApplicationType.ApplicationGroup")

	    Split:
	       GB1:     new HubGroupBy(hubMRADClient, "MRADClient.Application.ApplicationType")
	       GB2:     new HubGroupBy(hubApplicationGroup, "ApplicationTypes")
	       GBNew:   hubCombined is updated using setupSlit


	      OAGroupBy   GB1       GB2          GBNew
	      .A          appType   appType      appGroup
	      .hubB       mrads     appGroups    mrads

	 
* This is used when a propertyPath has a link where one of the createMethod=false. By having the source hub * for the leftmost HubB, and must also have the source HubA for the rightmost, two separate hgb can be used to update a 3rd * hgb. This will set up the listeners for hgb1 & hgb2 to update this.hubCombined. */ private void setupSplit() { // A: hubGroup1 (hgb1) left part of pp, using hubB as the root // A.1: listen to hgb1 add/removes and update this.hubCombined hubGB1.addHubListener(new HubListenerAdapter() { @Override public void afterInsert(HubEvent e) { afterAdd(e); } @Override public void afterAdd(HubEvent e) { OAGroupBy gb1 = (OAGroupBy) e.getObject(); if (gb1.getHub().size() == 0) { return; } final Object gb1A = gb1.getGroupBy(); OAGroupBy gb2Found = null; if (gb1A != null) { for (OAGroupBy gb2 : hubGB2) { if (gb2.getGroupBy() == gb1A) { gb2Found = gb2; break; } } } if (gb2Found == null || gb2Found.getHub().getSize() == 0) { // add to empty list if (!bCreateNullList) { return; } OAGroupBy gbNewFound = null; for (OAGroupBy gbNew : HubGroupBy.this.getCombinedHub()) { if (gbNew.getGroupBy() == null) { gbNewFound = gbNew; break; } } if (gbNewFound == null) { gbNewFound = createGroupBy(null); HubGroupBy.this.getCombinedHub().add(gbNewFound); } for (Object gb1B : gb1.getHub()) { gbNewFound.getHub().add(gb1B); } return; } for (Object gb2B : gb2Found.getHub()) { OAObject objGB2b = (OAObject) gb2B; OAGroupBy gbNewFound = null; for (OAGroupBy gbNew : HubGroupBy.this.getCombinedHub()) { if (gbNew.getGroupBy() == objGB2b) { gbNewFound = gbNew; break; } } if (gbNewFound == null) { gbNewFound = createGroupBy((G) objGB2b); HubGroupBy.this.getCombinedHub().add(gbNewFound); } for (Object gb1B : gb1.getHub()) { gbNewFound.getHub().add(gb1B); } } // remove from gbNew.A=null hubB if (!bCreateNullList) { return; } OAGroupBy gbNewFound = null; for (OAGroupBy gbNew : HubGroupBy.this.getCombinedHub()) { if (gbNew.getGroupBy() == null) { gbNewFound = gbNew; break; } } if (gbNewFound != null) { for (Object gb1B : gb1.getHub()) { gbNewFound.getHub().remove(gb1B); } } } Object[] removeObjects; @Override public void beforeRemoveAll(HubEvent e) { removeObjects = hubGB1.toArray(); } @Override public void afterRemoveAll(HubEvent e) { if (removeObjects != null) { for (Object obj : removeObjects) { remove((OAGroupBy) obj); } removeObjects = null; } } @Override public void afterRemove(HubEvent e) { OAGroupBy gb1 = (OAGroupBy) e.getObject(); if (gb1.getHub().size() == 0) { return; } remove(gb1); } void remove(OAGroupBy gb1) { final OAObject gb1A = gb1.getGroupBy(); OAGroupBy gb2Found = null; if (gb1A != null) { for (OAGroupBy gb2 : hubGB2) { if (gb2.getGroupBy() == gb1A) { gb2Found = gb2; break; } } } if (gb2Found == null || gb2Found.getHub().getSize() == 0) { // remove from empty list if (!bCreateNullList) { return; } OAGroupBy gbNewFound = null; for (OAGroupBy gbNew : HubGroupBy.this.getCombinedHub()) { if (gbNew.getGroupBy() == null) { gbNewFound = gbNew; break; } } if (gbNewFound == null) { return; } for (Object gb1B : gb1.getHub()) { gbNewFound.getHub().remove(gb1B); } return; } for (Object gb2B : gb2Found.getHub()) { OAObject objGB2b = (OAObject) gb2B; OAGroupBy gbNewFound = null; for (OAGroupBy gbNew : HubGroupBy.this.getCombinedHub()) { if (gbNew.getGroupBy() == objGB2b) { gbNewFound = gbNew; break; } } if (gbNewFound == null) { continue; } for (Object gb1B : gb1.getHub()) { gbNewFound.getHub().remove(gb1B); } } // see if it needs to be added to gbNew.A=null hubB if (!bCreateNullList) { return; } OAGroupBy gbNewFound = null; for (Object gb1B : gb1.getHub()) { if (!hubFrom.contains(gb1B)) { continue; // no longer in the From list } boolean bFound = false; for (OAGroupBy gbNew : HubGroupBy.this.getCombinedHub()) { if (gbNew.getGroupBy() == null) { gbNewFound = gbNew; continue; } if (gbNew.getHub().contains(gb1B)) { bFound = true; break; } } if (bFound) { continue; } if (gbNewFound == null) { gbNewFound = createGroupBy(null); HubGroupBy.this.getCombinedHub().add(gbNewFound); } gbNewFound.getHub().add(gb1B); } } }); // A.2: listen to changes to hgb1.hubB changes by using a hubmerger to get add/remove events and update this.hubCombined Hub hubTemp = new Hub(OAObject.class); HubMerger hm1 = new HubMerger(hubGB1, hubTemp, OAGroupBy.P_Hub, true) { @Override protected void afterInsertRealHub(HubEvent e) { afterAddRealHub(e); } @Override protected void afterAddRealHub(HubEvent e) { OAGroupBy gb = (OAGroupBy) ((Hub) e.getSource()).getMasterObject(); final OAObject gb1A = gb.getGroupBy(); Object gb1B = e.getObject(); // object added OAGroupBy gb2Found = null; if (gb1A != null) { for (OAGroupBy gb2 : hubGB2) { if (gb2.getGroupBy() == gb1A) { gb2Found = gb2; break; } } } if (gb2Found == null || gb2Found.getHub().getSize() == 0) { // add to empty list if (!bCreateNullList) { return; } OAGroupBy gbNewFound = null; for (OAGroupBy gbNew : HubGroupBy.this.getCombinedHub()) { if (gbNew.getGroupBy() == null) { gbNewFound = gbNew; break; } } if (gbNewFound == null) { gbNewFound = createGroupBy(null); HubGroupBy.this.getCombinedHub().add(gbNewFound); } gbNewFound.getHub().add(gb1B); return; } for (Object gb2B : gb2Found.getHub()) { OAObject objGB2b = (OAObject) gb2B; OAGroupBy gbNewFound = null; for (OAGroupBy gbNew : HubGroupBy.this.getCombinedHub()) { if (gbNew.getGroupBy() == objGB2b) { gbNewFound = gbNew; break; } } if (gbNewFound == null) { gbNewFound = createGroupBy((G) objGB2b); HubGroupBy.this.getCombinedHub().add(gbNewFound); } gbNewFound.getHub().add(gb1B); } //remove from null hub if (!bCreateNullList) { return; } OAGroupBy gbNewFound = null; for (OAGroupBy gbNew : HubGroupBy.this.getCombinedHub()) { if (gbNew.getGroupBy() == null) { gbNew.getHub().remove(gb1B); break; } } } private Object[] removeAllObjects; @Override protected void beforeRemoveAllRealHub(HubEvent e) { removeAllObjects = ((Hub) e.getSource()).toArray(); } @Override protected void afterRemoveAllRealHub(HubEvent e) { if (removeAllObjects == null) { return; } OAGroupBy gb1 = (OAGroupBy) ((Hub) e.getSource()).getMasterObject(); for (Object obj : removeAllObjects) { remove(gb1, (OAGroupBy) obj); } removeAllObjects = null; } @Override protected void afterRemoveRealHub(HubEvent e) { OAGroupBy gb1 = (OAGroupBy) ((Hub) e.getSource()).getMasterObject(); Object gb1B = e.getObject(); remove(gb1, gb1B); } void remove(final OAGroupBy gb1, final Object gb1B) { final OAObject gb1A = gb1.getGroupBy(); OAGroupBy gb2Found = null; if (gb1A != null) { for (OAGroupBy gb2 : hubGB2) { if (gb2.getGroupBy() == gb1A) { gb2Found = gb2; break; } } } if (gb2Found == null || gb2Found.getHub().getSize() == 0) { // remove from empty list if (!bCreateNullList) { return; } if (hgb1.hubFrom.contains(gb1B)) { return; } OAGroupBy gbNewFound = null; for (OAGroupBy gbNew : HubGroupBy.this.getCombinedHub()) { if (gbNew.getGroupBy() == null) { gbNewFound = gbNew; break; } } if (gbNewFound == null) { return; } gbNewFound.getHub().remove(gb1B); return; } for (Object gb2B : gb2Found.getHub()) { OAObject objGB2b = (OAObject) gb2B; OAGroupBy gbNewFound = null; for (OAGroupBy gbNew : HubGroupBy.this.getCombinedHub()) { if (gbNew.getGroupBy() == objGB2b) { gbNewFound = gbNew; break; } } if (gbNewFound == null) { continue; } gbNewFound.getHub().remove(gb1B); } if (!HubGroupBy.this.hubFrom.contains(gb1B)) { return; } // see if it needs to be added to gbNew.A=null hubB if (!bCreateNullList) { return; } OAGroupBy gbNewFound = null; boolean bFound = false; for (OAGroupBy gbNew : HubGroupBy.this.getCombinedHub()) { if (gbNew.getGroupBy() == null) { gbNewFound = gbNew; continue; } if (gbNew.getHub().contains(gb1B)) { bFound = true; break; } } if (!bFound) { if (gbNewFound == null) { gbNewFound = createGroupBy(null); HubGroupBy.this.getCombinedHub().add(gbNewFound); } gbNewFound.getHub().add(gb1B); } } }; // B: hubGroup2 (hgb2) right reverse part of pp, using hubA as the root // B.1: listen to hgb2 add/removes and update this.hubCombined // listen to GB2 hubGB2.addHubListener(new HubListenerAdapter() { @Override public void afterInsert(HubEvent e) { afterAdd(e); } @Override public void afterAdd(HubEvent e) { OAGroupBy gb2 = (OAGroupBy) e.getObject(); final OAObject gb2A = gb2.getGroupBy(); OAGroupBy gb1Found = null; if (gb2A != null) { for (OAGroupBy gb1 : hubGB1) { if (gb1.getGroupBy() == gb2A) { gb1Found = gb1; break; } } } if (gb1Found == null) { for (Object gb2B : gb2.getHub()) { OAGroupBy gbNewFound = null; for (OAGroupBy gbNew : HubGroupBy.this.getCombinedHub()) { if (gbNew.getGroupBy() == gb2B) { gbNewFound = gbNew; break; } } if (gbNewFound == null) { gbNewFound = createGroupBy((G) gb2B); HubGroupBy.this.getCombinedHub().add(gbNewFound); } } return; } for (Object gb2B : gb2.getHub()) { OAGroupBy gbNewFound = null; for (OAGroupBy gbNew : HubGroupBy.this.getCombinedHub()) { if (gbNew.getGroupBy() == gb2B) { gbNewFound = gbNew; break; } } if (gbNewFound == null) { gbNewFound = createGroupBy((G) gb2B); HubGroupBy.this.getCombinedHub().add(gbNewFound); } for (Object gb1B : gb1Found.getHub()) { gbNewFound.getHub().add(gb1B); } // might have been in gbNew.A=null gbNew.hubB if (!bCreateNullList) { continue; } for (OAGroupBy gbNew : HubGroupBy.this.getCombinedHub()) { if (gbNew.getGroupBy() == null) { for (Object gb1B : gb1Found.getHub()) { gbNew.getHub().remove(gb1B); } break; } } } } Object[] removeObjects; @Override public void beforeRemoveAll(HubEvent e) { removeObjects = hubGB2.toArray(); } @Override public void afterRemoveAll(HubEvent e) { if (removeObjects != null) { for (Object obj : removeObjects) { remove((OAGroupBy) obj); } removeObjects = null; } } @Override public void afterRemove(HubEvent e) { OAGroupBy gb2 = (OAGroupBy) e.getObject(); remove(gb2); } void remove(OAGroupBy gb2) { final Object gb2A = gb2.getGroupBy(); OAGroupBy gb1Found = null; if (gb2A != null) { for (OAGroupBy gb1 : hubGB1) { if (gb1.getGroupBy() == gb2A) { gb1Found = gb1; break; } } } if (gb1Found == null || gb1Found.getHub().getSize() == 0) { for (Object gb2B : gb2.getHub()) { if (hubGroupBy != null && hubGroupBy.contains(gb2B)) { continue; } for (OAGroupBy gbNew : HubGroupBy.this.getCombinedHub()) { if (gbNew.getGroupBy() == gb2B) { if (gbNew.getHub().size() == 0) { HubGroupBy.this.getCombinedHub().remove(gbNew); } break; } } } return; } for (Object gb2B : gb2.getHub()) { OAGroupBy gbNewFound = null; for (OAGroupBy gbNew : HubGroupBy.this.getCombinedHub()) { if (gbNew.getGroupBy() == gb2B) { gbNewFound = gbNew; break; } } if (gbNewFound == null) { if (!bCreateNullList) { continue; } for (OAGroupBy gbNew : HubGroupBy.this.getCombinedHub()) { if (gbNew.getGroupBy() == null) { gbNewFound = gbNew; break; } } if (gbNewFound == null) { continue; } } for (Object gb1B : gb1Found.getHub()) { // ??? note: dont remove from hubB if it's still used for another path gbNewFound.getHub().remove(gb1B); } if (gbNewFound.getHub().size() == 0) { if (hubGroupBy == null || !hubGroupBy.contains(gbNewFound.getGroupBy())) { HubGroupBy.this.getCombinedHub().remove(gbNewFound); } } // add to gbNew.A=null gbNew.hubB if (!bCreateNullList) { continue; } gbNewFound = null; for (OAGroupBy gbNew : HubGroupBy.this.getCombinedHub()) { if (gbNew.getGroupBy() == null) { gbNewFound = gbNew; break; } } if (gbNewFound == null) { gbNewFound = createGroupBy(null); HubGroupBy.this.getCombinedHub().add(gbNewFound); } for (Object gb1B : gb1Found.getHub()) { gbNewFound.getHub().add(gb1B); } } } }); // B.2: listen to changes to hgb2.hubB changes by using a hubmerger to get add/remove events and update this.hubCombined Hub hubTemp2 = new Hub(OAObject.class); HubMerger hm2 = new HubMerger(hubGB2, hubTemp2, OAGroupBy.P_Hub, true) { @Override protected void afterInsertRealHub(HubEvent e) { afterAddRealHub(e); } @Override protected void afterAddRealHub(HubEvent e) { OAGroupBy gb2 = (OAGroupBy) ((Hub) e.getSource()).getMasterObject(); final Object gb2A = gb2.getGroupBy(); Object gb2B = e.getObject(); // object added OAGroupBy gb1Found = null; if (gb2A != null) { for (OAGroupBy gb1 : hubGB1) { if (gb1.getGroupBy() == gb2A) { gb1Found = gb1; break; } } } if (gb1Found == null) { OAGroupBy gbNewFound = null; for (OAGroupBy gbNew : HubGroupBy.this.getCombinedHub()) { if (gbNew.getGroupBy() == gb2B) { gbNewFound = gbNew; break; } } if (gbNewFound == null) { gbNewFound = createGroupBy((G) gb2B); HubGroupBy.this.getCombinedHub().add(gbNewFound); } return; } OAGroupBy gbNewFound = null; OAGroupBy gbNewNullFound = null; for (OAGroupBy gbNew : HubGroupBy.this.getCombinedHub()) { if (gbNew.getGroupBy() == null) { gbNewNullFound = gbNew; if (gbNewFound != null) { break; } } else if (gbNew.getGroupBy() == gb2B) { gbNewFound = gbNew; if (gbNewNullFound != null) { break; } } } if (gbNewFound == null) { gbNewFound = createGroupBy((G) gb2B); HubGroupBy.this.getCombinedHub().add(gbNewFound); } if (gb1Found == null) { return; } for (Object gb1B : gb1Found.getHub()) { gbNewFound.getHub().add(gb1B); // remove from null hub if (gbNewNullFound != null) { gbNewNullFound.getHub().remove(gb1B); } } } private Object[] removeAllObjects; @Override protected void beforeRemoveAllRealHub(HubEvent e) { removeAllObjects = ((Hub) e.getSource()).toArray(); } @Override protected void afterRemoveAllRealHub(HubEvent e) { if (removeAllObjects == null) { return; } OAGroupBy gb2 = (OAGroupBy) ((Hub) e.getSource()).getMasterObject(); for (Object obj : removeAllObjects) { remove(gb2, (OAGroupBy) obj); } removeAllObjects = null; } @Override protected void afterRemoveRealHub(HubEvent e) { OAGroupBy gb2 = (OAGroupBy) ((Hub) e.getSource()).getMasterObject(); Object gb2B = e.getObject(); remove(gb2, gb2B); } void remove(OAGroupBy gb2, final Object gb2B) { final Object gb2A = gb2.getGroupBy(); if (gb2A == null) { boolean bFound = false; for (OAGroupBy gb : hubGB2) { if (gb.getGroupBy() == null) { continue; } if (gb.getHub().contains(gb2B)) { bFound = true; break; } } if (!bFound) { for (OAGroupBy gbNew : HubGroupBy.this.getCombinedHub()) { if (gbNew.getGroupBy() == gb2B) { if (gbNew.getHub().size() == 0) { HubGroupBy.this.getCombinedHub().remove(gbNew); } break; } } } return; } OAGroupBy gb1Found = null; for (OAGroupBy gb1 : hubGB1) { if (gb1.getGroupBy() == gb2A) { gb1Found = gb1; break; } } if (gb1Found == null || gb1Found.getHub().getSize() == 0) { if (hubGroupBy.contains(gb2B)) { return; } } OAGroupBy gbNewFound = null; for (OAGroupBy gbNew : HubGroupBy.this.getCombinedHub()) { if (gbNew.getGroupBy() == gb2B) { gbNewFound = gbNew; break; } } if (gbNewFound == null) { return; } if (gb1Found != null) { for (Object gb1B : gb1Found.getHub()) { // ??? note: dont remove from hubB if it's still used for another path gbNewFound.getHub().remove(gb1B); } } if (gbNewFound.getHub().size() == 0) { if (hubGroupBy == null || !hubGroupBy.contains(gbNewFound.getGroupBy())) { HubGroupBy.this.getCombinedHub().remove(gbNewFound); } } if (!bCreateNullList) { return; } if (gb1Found != null && gb2.getHub().size() == 0) { // need to add to gbNew.a=null hubB gbNewFound = null; for (OAGroupBy gbNew : HubGroupBy.this.getCombinedHub()) { if (gbNew.getGroupBy() == null) { gbNewFound = gbNew; break; } } if (gbNewFound == null) { gbNewFound = createGroupBy(null); HubGroupBy.this.getCombinedHub().add(gbNewFound); } for (Object gb1B : gb1Found.getHub()) { gbNewFound.getHub().add(gb1B); } } } }; // C: initial load for this.hubCombined using GB1 for (OAGroupBy gb1 : hubGB1) { OAObject gb1A = (OAObject) gb1.getGroupBy(); boolean bFound = false; OAGroupBy gb2Found = null; for (OAGroupBy gb2 : hubGB2) { if (gb2.getGroupBy() == gb1A) { gb2Found = gb2; } } if (gb2Found == null || gb2Found.getHub().getSize() == 0) { // add to empty list if (!bCreateNullList) { continue; } OAGroupBy gbNewFound = null; for (OAGroupBy gbNew : HubGroupBy.this.getCombinedHub()) { if (gbNew.getGroupBy() == null) { gbNewFound = gbNew; break; } } if (gbNewFound == null) { gbNewFound = createGroupBy(null); HubGroupBy.this.getCombinedHub().add(gbNewFound); } for (Object gb1B : gb1.getHub()) { gbNewFound.getHub().add(gb1B); } continue; } for (Object gb2B : gb2Found.getHub()) { OAObject objGB2b = (OAObject) gb2B; OAGroupBy gbNewFound = null; for (OAGroupBy gbNew : HubGroupBy.this.getCombinedHub()) { if (gbNew.getGroupBy() == objGB2b) { gbNewFound = gbNew; break; } } if (gbNewFound == null) { gbNewFound = createGroupBy((G) objGB2b); HubGroupBy.this.getCombinedHub().add(gbNewFound); } for (Object gb1B : gb1.getHub()) { gbNewFound.getHub().add(gb1B); } } } } // main setup, if not needing a split void setupMain() { getCombinedHub().addHubListener(new HubListenerAdapter() { @Override public void afterChangeActiveObject(HubEvent e) { if (bIgnoreAOChange) { return; } try { // set the active object in hub A&B when hubCombine.AO is changed OAGroupBy obj = (OAGroupBy) e.getObject(); if (obj == null) { if (hubGroupBy != null) { hubGroupBy.setAO(null); } if (hubMaster != null) { hubMaster.setAO(null); } } else { if (hubGroupBy != null) { hubGroupBy.setAO(obj.getGroupBy()); } if (hubMaster != null) { hubMaster.setAO(obj.getGroupBy()); } } hubFrom.setAO(null); if (hubDetail != null) { hubDetail.setAO(null); } } finally { bIgnoreAOChange = false; } } }); if (hubGroupBy != null) { hubGroupBy.addHubListener(new HubListenerAdapter() { @Override public void afterInsert(HubEvent e) { afterAdd(e); } @Override public void afterAdd(HubEvent e) { G a = (G) e.getObject(); boolean bFound = false; for (OAGroupBy c : HubGroupBy.this.getCombinedHub()) { if (c.getGroupBy() == a) { bFound = true; break; } } if (!bFound) { OAGroupBy gbNewFound = createGroupBy(a); HubGroupBy.this.hubCombined.add(gbNewFound); } } Object[] removeObjects; @Override public void beforeRemoveAll(HubEvent e) { removeObjects = hubGroupBy.toArray(); } @Override public void afterRemoveAll(HubEvent e) { for (Object obj : removeObjects) { remove((G) obj); } removeObjects = null; } @Override public void afterRemove(HubEvent e) { G a = (G) e.getObject(); remove(a); } void remove(G a) { for (OAGroupBy c : HubGroupBy.this.getCombinedHub()) { if (c.getGroupBy() == a) { HubGroupBy.this.hubCombined.remove(c); break; } } } @Override public void onNewList(HubEvent e) { HubGroupBy.this.hubCombined.clear(); for (G a : hubGroupBy) { OAGroupBy gbNewFound = createGroupBy(a); HubGroupBy.this.hubCombined.add(gbNewFound); } addAll(); } }); for (G a : hubGroupBy) { boolean bFound = false; for (OAGroupBy c : HubGroupBy.this.getCombinedHub()) { if (c.getGroupBy() == a) { bFound = true; break; } } if (!bFound) { OAGroupBy gbNewFound = createGroupBy(a); HubGroupBy.this.hubCombined.add(gbNewFound); } } } HubListener hl = new HubListenerAdapter() { @Override public void afterInsert(HubEvent e) { afterAdd(e); } @Override public void afterAdd(HubEvent e) { F b = (F) e.getObject(); add(b); } Object[] removeObjects; @Override public void beforeRemoveAll(HubEvent e) { removeObjects = hubFrom.toArray(); } @Override public void afterRemoveAll(HubEvent e) { if (removeObjects == null) { return; } for (Object obj : removeObjects) { remove((F) obj); } removeObjects = null; } @Override public void afterRemove(HubEvent e) { F b = (F) e.getObject(); remove(b); } @Override public void afterPropertyChange(HubEvent e) { String s = e.getPropertyName(); if (!listenPropertyName.equalsIgnoreCase(s)) { return; } update((F) e.getObject()); } @Override public void onNewList(HubEvent e) { try { bIgnoreAOChange = true; HubGroupBy.this.getCombinedHub().clear(); } finally { bIgnoreAOChange = false; } if (hubGroupBy != null) { for (G a : hubGroupBy) { OAGroupBy gbNewFound = createGroupBy(a); HubGroupBy.this.hubCombined.add(gbNewFound); } } addAll(); } @Override public void afterChangeActiveObject(HubEvent e) { if (bIgnoreAOChange) { return; } bIgnoreAOChange = true; try { F ao = (F) e.getObject(); if (ao == null) { HubGroupBy.this.hubCombined.setAO(null); if (hubMaster != null) { hubMaster.setAO(null); } if (hubDetail != null) { hubDetail.setAO(null); } } else { boolean bFound = false; for (OAGroupBy gb : HubGroupBy.this.getCombinedHub()) { Hub h = gb.getHub(); if (!h.contains(ao)) { continue; } bFound = true; HubGroupBy.this.hubCombined.setAO(gb); h.setAO(ao); if (hubMaster != null) { hubMaster.setAO(gb.getGroupBy()); } if (hubDetail != null) { hubDetail.setAO(ao); } break; } if (!bFound) { HubGroupBy.this.hubCombined.setAO(null); if (hubMaster != null) { hubMaster.setAO(null); } if (hubDetail != null) { hubDetail.setAO(null); } } } } finally { bIgnoreAOChange = false; } } }; boolean b = false; if (propertyPath == null) { b = true; } else if (propertyPath.indexOf('.') < 0) { // propertyPath could be a hub OAObjectInfo oi = OAObjectInfoDelegate.getOAObjectInfo(classFrom); OALinkInfo li = oi.getLinkInfo(propertyPath); if (li == null || li.getType() == li.ONE) { b = true; } // else it's a hub } if (b) { listenPropertyName = propertyPath; hubFrom.addHubListener(hl, propertyPath); } else { listenPropertyName = "hubGroupBy" + aiCnt.getAndIncrement(); hubFrom.addHubListener(hl, listenPropertyName, new String[] { propertyPath }); } addAll(); } private void addAll() { // this will tell the OASyncClient.getDetail which hub objects are being used final OASiblingHelper siblingHelper = new OASiblingHelper(this.hubFrom); siblingHelper.add(this.propertyPath); OAThreadLocalDelegate.addSiblingHelper(siblingHelper); try { OAThreadLocalDelegate.setSuppressCSMessages(true); for (F bx : hubFrom) { add(bx); } } finally { OAThreadLocalDelegate.setSuppressCSMessages(false); OAThreadLocalDelegate.removeSiblingHelper(siblingHelper); } } private ArrayList add(F b) { return add(b, false); } private ArrayList add(F b, boolean bReturnList) { if (b == null) { return null; } Object valueA = b.getProperty(propertyPath); ArrayList al = null; if (valueA instanceof Hub) { Hub h = (Hub) valueA; for (int i = 0;; i++) { valueA = h.getAt(i); if (valueA == null) { break; } boolean bFound = false; for (OAGroupBy gb : HubGroupBy.this.getCombinedHub()) { if (gb.getGroupBy() != valueA) { continue; } if (bReturnList) { if (al == null) { al = new ArrayList(); } al.add(gb); } gb.getHub().add(b); bFound = true; break; } if (!bFound) { // create new OAGroupBy gbNewFound = createGroupBy((G) valueA); HubGroupBy.this.hubCombined.add(gbNewFound); gbNewFound.getHub().add(b); if (bReturnList) { if (al == null) { al = new ArrayList(); } al.add(gbNewFound); } } } // add to empty hub if (h.size() == 0 && bCreateNullList) { for (OAGroupBy gb : HubGroupBy.this.getCombinedHub()) { if (gb.getGroupBy() != null) { continue; } gb.getHub().add(b); if (bReturnList) { if (al == null) { al = new ArrayList(); } al.add(gb); } return al; } // create new OAGroupBy gb = createGroupBy(null); HubGroupBy.this.hubCombined.add(gb); gb.getHub().add(b); if (bReturnList) { if (al == null) { al = new ArrayList(); } al.add(gb); } } } else { if (!bCreateNullList && valueA == null) { return al; } for (OAGroupBy gb : HubGroupBy.this.getCombinedHub()) { if (gb.getGroupBy() != valueA) { continue; } gb.getHub().add(b); if (bReturnList) { if (al == null) { al = new ArrayList(); } al.add(gb); } return al; } // create new OAGroupBy c = createGroupBy((G) valueA); HubGroupBy.this.hubCombined.add(c); c.getHub().add(b); if (bReturnList) { if (al == null) { al = new ArrayList(); } al.add(c); } } return al; } private void remove(G a, F b) { for (OAGroupBy gb : HubGroupBy.this.getCombinedHub()) { G ax = (G) gb.getGroupBy(); if (ax != a) { continue; } Hub h = gb.getHub(); if (h.contains(b)) { h.remove(b); return; } } } private void remove(F b) { for (OAGroupBy gb : getCombinedHub()) { Hub h = gb.getHub(); if (h.contains(b)) { h.remove(b); if (h.size() == 0) { if (hubGroupBy == null || !hubGroupBy.contains(gb.getGroupBy())) { hubCombined.remove(gb); } } } } } private void update(F b) { ArrayList al = add(b, true); for (OAGroupBy gb : getCombinedHub()) { Hub h = gb.getHub(); if (al != null) { if (al.contains(gb)) { continue; } } if (h.contains(b)) { h.remove(b); } } } void setupCombined(HubGroupBy hgb1, HubGroupBy hgb2) { final Hub> hub1 = hgb1.getCombinedHub(); final Hub> hub2 = hgb2.getCombinedHub(); getCombinedHub(); HubListener> hl = new HubListenerAdapter>() { /* Hub> getOtherHub(HubEvent e) { if (e.getSource() == hub1) return hub2; return hub1; } */ @Override public void afterAdd(HubEvent> e) { final OAGroupBy gb = e.getObject(); OAGroupBy gbFound = null; G a = (G) gb.getGroupBy(); for (OAGroupBy c : HubGroupBy.this.getCombinedHub()) { if (c.getGroupBy() == a) { gbFound = c; break; } } if (gbFound == null) { gbFound = createGroupBy(a); HubGroupBy.this.getCombinedHub().add(gbFound); } for (OAObject obj : gb.getHub()) { gbFound.getHub().add(obj); } } @Override public void afterInsert(HubEvent e) { afterAdd(e); } @Override public void afterRemove(HubEvent> e) { final OAGroupBy gb = e.getObject(); OAGroupBy gbFound = null; G a = (G) gb.getGroupBy(); for (OAGroupBy c : HubGroupBy.this.getCombinedHub()) { if (c.getGroupBy() == a) { gbFound = c; break; } } if (gbFound == null) { return; } for (OAObject obj : gb.getHub()) { boolean bStillNeeded = false; for (OAGroupBy gbx : hub1) { if (gbx.getGroupBy() == a) { if (gbx.getHub().contains(obj)) { bStillNeeded = true; break; } } } for (OAGroupBy gbx : hub2) { if (gbx.getGroupBy() == a) { if (gbx.getHub().contains(obj)) { bStillNeeded = true; break; } } } if (!bStillNeeded) { gbFound.getHub().remove(obj); } } } void rebuild() { HubGroupBy.this.getCombinedHub().clear(); OAGroupBy gbFound = null; for (OAGroupBy gb : hub1) { gbFound = createGroupBy(gb.getGroupBy()); HubGroupBy.this.hubCombined.add(gbFound); for (F obj : gb.getHub()) { gbFound.getHub().add(obj); } } for (OAGroupBy gb : hub2) { gbFound = null; G a = (G) gb.getGroupBy(); for (OAGroupBy c : HubGroupBy.this.getCombinedHub()) { if (c.getGroupBy() == a) { gbFound = c; break; } } if (gbFound == null) { gbFound = createGroupBy(a); HubGroupBy.this.hubCombined.add(gbFound); } for (F obj : gb.getHub()) { gbFound.getHub().add(obj); } } } @Override public void afterRemoveAll(HubEvent> e) { rebuild(); } @Override public void onNewList(HubEvent e) { rebuild(); } }; hub1.addHubListener(hl); hub2.addHubListener(hl); // set up hubMergers //qqqqqq this fails //Hub hubTemp1 = new Hub(); //qq this works Hub hubTemp1 = new Hub(OAObject.class); HubMerger, F> hm1 = new HubMerger, F>(hub1, (Hub) hubTemp1, OAGroupBy.P_Hub, true) { @Override protected void afterInsertRealHub(HubEvent e) { afterAddRealHub(e); } @Override protected void afterAddRealHub(HubEvent e) { final OAGroupBy gb = (OAGroupBy) e.getHub().getMasterObject(); final F objAdd = (F) e.getObject(); OAGroupBy gbFound = null; G a = (G) gb.getGroupBy(); if (a == null) { if (!bCreateNullList) { return; } // only add if its in the other hgb null for (OAGroupBy gbx : hub2) { if (gbx.getGroupBy() == null) { if (!gbx.getHub().contains(objAdd)) { return; } } } } for (OAGroupBy c : HubGroupBy.this.getCombinedHub()) { if (c.getGroupBy() == a) { gbFound = c; break; } } if (gbFound == null) { gbFound = createGroupBy(a); HubGroupBy.this.getCombinedHub().add(gbFound); } gbFound.getHub().add(objAdd); } @Override protected void afterRemoveRealHub(HubEvent e) { OAGroupBy gb = (OAGroupBy) e.getHub().getMasterObject(); F objRemove = (F) e.getObject(); remove(gb, objRemove); } void remove(final OAGroupBy gb, final F objRemove) { OAGroupBy gbFound = null; final G a = (G) gb.getGroupBy(); for (OAGroupBy c : HubGroupBy.this.getCombinedHub()) { if (c.getGroupBy() == a) { gbFound = c; break; } } if (gbFound == null) { return; } boolean bStillNeeded = false; if (a != null) { for (OAGroupBy gbx : hub2) { if (gbx.getGroupBy() == a) { if (gbx.getHub().contains(objRemove)) { bStillNeeded = true; break; } } } } if (!bStillNeeded) { gbFound.getHub().remove(objRemove); } } private Object[] removeAllObjects; @Override protected void beforeRemoveAllRealHub(HubEvent e) { removeAllObjects = ((Hub) e.getSource()).toArray(); } @Override protected void afterRemoveAllRealHub(HubEvent e) { if (removeAllObjects == null) { return; } OAGroupBy gb1 = (OAGroupBy) ((Hub) e.getSource()).getMasterObject(); for (Object obj : removeAllObjects) { remove(gb1, (F) obj); } removeAllObjects = null; } }; Hub hubTemp2 = new Hub(OAObject.class); HubMerger, F> hm2 = new HubMerger, F>(hub2, (Hub) hubTemp2, OAGroupBy.P_Hub, true) { @Override protected void afterInsertRealHub(HubEvent e) { afterAddRealHub(e); } @Override protected void afterAddRealHub(HubEvent e) { final OAGroupBy gb = (OAGroupBy) e.getHub().getMasterObject(); final F objAdd = (F) e.getObject(); OAGroupBy gbFound = null; G a = (G) gb.getGroupBy(); if (a == null) { if (!bCreateNullList) { return; } // only add if its in the other hgb null for (OAGroupBy gbx : hub2) { if (gbx.getGroupBy() == null) { if (!gbx.getHub().contains(objAdd)) { return; } } } } for (OAGroupBy c : HubGroupBy.this.getCombinedHub()) { if (c.getGroupBy() == a) { gbFound = c; break; } } if (gbFound == null) { gbFound = createGroupBy(a); HubGroupBy.this.hubCombined.add(gbFound); } gbFound.getHub().add(objAdd); } @Override protected void afterRemoveRealHub(HubEvent e) { OAGroupBy gb = (OAGroupBy) e.getHub().getMasterObject(); F objRemove = (F) e.getObject(); remove(gb, objRemove); } void remove(final OAGroupBy gb, final F objRemove) { OAGroupBy gbFound = null; final G a = (G) gb.getGroupBy(); for (OAGroupBy c : HubGroupBy.this.getCombinedHub()) { if (c.getGroupBy() == a) { gbFound = c; break; } } if (gbFound == null) { return; } boolean bStillNeeded = false; if (a != null) { for (OAGroupBy gbx : hub1) { if (gbx.getGroupBy() == a) { if (gbx.getHub().contains(objRemove)) { bStillNeeded = true; break; } } } } if (!bStillNeeded) { gbFound.getHub().remove(objRemove); } } private Object[] removeAllObjects; @Override protected void beforeRemoveAllRealHub(HubEvent e) { removeAllObjects = ((Hub) e.getSource()).toArray(); } @Override protected void afterRemoveAllRealHub(HubEvent e) { if (removeAllObjects == null) { return; } OAGroupBy gb1 = (OAGroupBy) ((Hub) e.getSource()).getMasterObject(); for (Object obj : removeAllObjects) { remove(gb1, (F) obj); } removeAllObjects = null; } }; // initial load for (int i = 0; i < 2; i++) { Hub> hub; if (i == 0) { hub = hub1; } else { hub = hub2; } for (OAGroupBy gb : hub) { OAGroupBy gbFound = null; G a = (G) gb.getGroupBy(); if (!bCreateNullList && a == null) { continue; } for (OAGroupBy c : HubGroupBy.this.getCombinedHub()) { if (c.getGroupBy() == a) { gbFound = c; break; } } if (gbFound == null) { gbFound = createGroupBy(a); HubGroupBy.this.getCombinedHub().add(gbFound); } for (F obj : gb.getHub()) { gbFound.getHub().add(obj); } } } } private OAGroupBy createGroupBy(G grpBy) { OAGroupBy gb = new OAGroupBy(); if (grpBy != null) { gb.setGroupBy(grpBy); } HubDelegate.setObjectClass(gb.getHub(), classFrom); // 20190418 if hubPropertyName!=null, then use a HubCopy if (OAString.isNotEmpty(hubPropertyName)) { new HubCopy(gb.getHub(), (Hub) grpBy.getProperty(hubPropertyName), false); } return gb; } public String getGroupByPP() { if (classGroupBy == null) { return null; } String s = "(" + classGroupBy.toString() + ")GroupBy"; return s; } public String getHubByPP() { return "(" + classFrom.toString() + ")hub"; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy