![JAR search and dependency download from the Maven repository](/logo.png)
com.viaoa.hub.HubLeftJoin Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of oa-core Show documentation
Show all versions of oa-core Show documentation
Object Automation library
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.util.concurrent.atomic.AtomicInteger;
import com.viaoa.object.*;
import com.viaoa.util.OACompare;
import com.viaoa.util.OAString;
/*
* Combines two hubs into a new single hub to create the equivalent of
* a database left join, where all of the "left" side objects are in the list.
*
* The combined Hub (see getCombinedHub) uses OAObject OALeftJoin<A,B>, where A is the
* same class as the left Hub and B is the same as the right Hub.
*
* A property path that uses A or B will need to use casting.
* Example: LeftHub=hubDepartments, RightHub=hubEmployees with last name "Jones"
* the combined Hub A=Dept ref, B=Employee ref, can use hubCombined with properties
* from A or B, with casting:
* hubCombined, "(com.xxx.Department)A.manager.fullName"
* or : OAString.cpp(Departement.class, OALeftJoin.P_A, Department.P_Manager, Employee.P_FullName)
*
* see HubLeftJoinDetail#
* see HubGroupBy#
*
* @author vvia
*/
public class HubLeftJoin {
private Hub hubA;
private Hub hubB;
private Hub> hubCombined;
private String propertyPath;
private String listenPropertyName;
private boolean bSetAO;
private final static AtomicInteger aiCnt = new AtomicInteger();
/**
* Combine a left and right hubs on a propertyPath to form Hub.
*
* @param hubA left object
* @param hubB right object
* @param propertyPath pp of the property from the right object to get left object.
*/
public HubLeftJoin(Hub hubA, Hub hubB, String propertyPath) {
this(hubA, hubB, propertyPath, true);
}
public HubLeftJoin(Hub hubA, Hub hubB, String propertyPath, boolean bSetAO) {
this.hubA = hubA;
this.hubB = hubB;
this.bSetAO = bSetAO;
this.propertyPath = propertyPath;
setup();
}
/**
* @return Hub of combined objects
*/
public Hub> getCombinedHub() {
if (hubCombined != null) {
return hubCombined;
}
hubCombined = new Hub(OALeftJoin.class);
return hubCombined;
}
void setup() {
getCombinedHub().addHubListener(new HubListenerAdapter>() {
@Override
public void afterChangeActiveObject(HubEvent e) {
// set the active object in hub A&B when hubCombine.AO is changed
OALeftJoin obj = (OALeftJoin) e.getObject();
if (obj == null) {
hubA.setAO(null);
hubB.setAO(null);
} else {
hubA.setAO(obj.getA());
hubB.setAO(obj.getB());
}
}
@Override
public void afterPropertyChange(HubEvent> e) {
String name = e.getPropertyName();
if (OAString.isEmpty(name)) {
return;
}
if (!"b".equalsIgnoreCase(name)) {
return;
}
OALeftJoin lj = e.getObject();
if (lj == null) {
return;
}
Object oldValue = e.getOldValue();
Object newValue = e.getNewValue();
if (OACompare.isEqual(oldValue, newValue)) {
return;
}
if (oldValue != null) {
hubB.remove(oldValue);
}
if (newValue != null) {
hubB.add((B) newValue);
}
}
});
hubA.addHubListener(new HubListenerAdapter() {
@Override
public void afterInsert(HubEvent e) {
afterAdd(e);
}
@Override
public void afterAdd(HubEvent e) {
A a = (A) e.getObject();
OALeftJoin c = new OALeftJoin(a, null);
hubCombined.add(c);
}
@Override
public void afterRemove(HubEvent e) {
A a = (A) e.getObject();
for (;;) {
OALeftJoin c = hubCombined.find(OALeftJoin.P_A, a);
if (c == null) {
break;
}
hubCombined.remove(c);
}
}
@Override
public void onNewList(HubEvent e) {
hubCombined.clear();
for (A a : hubA) {
hubCombined.add(new OALeftJoin(a, null));
}
for (B b : hubB) {
add(b);
}
}
});
for (A a : hubA) {
hubCombined.add(new OALeftJoin(a, null));
}
HubListener hl = new HubListenerAdapter() {
@Override
public void afterInsert(HubEvent e) {
afterAdd(e);
}
@Override
public void afterAdd(HubEvent e) {
B b = (B) e.getObject();
add(b);
}
@Override
public void afterRemove(HubEvent e) {
B b = (B) e.getObject();
remove(b);
}
@Override
public void afterPropertyChange(HubEvent e) {
String s = e.getPropertyName();
if (!listenPropertyName.equalsIgnoreCase(s)) {
return;
}
remove((B) e.getObject());
add((B) e.getObject());
}
@Override
public void onNewList(HubEvent e) {
HubAddRemoveDelegate.clear(hubCombined, false, false); // 20240403 dont send newList event
OAThreadLocalDelegate.setLoading(true);
try {
for (A a : hubA) {
hubCombined.add(new OALeftJoin(a, null));
}
for (B b : hubB) {
add(b);
}
}
finally {
OAThreadLocalDelegate.setLoading(false);
hubCombined.setActiveObject(null);
HubEventDelegate.fireOnNewListEvent(hubCombined, true);
}
}
@Override
public void afterChangeActiveObject(HubEvent e) {
B b = (B) e.getObject();
OALeftJoin lj;
if (b != null) {
lj = hubCombined.find(OALeftJoin.P_B, b);
} else {
lj = null;
}
hubCombined.setAO(lj);
}
};
if (propertyPath == null || propertyPath.indexOf('.') < 0) {
listenPropertyName = propertyPath;
hubB.addHubListener(hl, propertyPath);
} else {
listenPropertyName = "hubCombined" + aiCnt.getAndIncrement();
hubB.addHubListener(hl, listenPropertyName, new String[] { propertyPath });
}
for (B b : hubB) {
add(b);
}
}
private void add(B b) {
Object valueA = b.getProperty(propertyPath);
boolean bFound = false;
OALeftJoin ljEmpty = null;
for (OALeftJoin lj : hubCombined) {
if (lj.getA() != valueA) {
continue;
}
B bx = (B) lj.getB();
if (bx == b) {
bFound = true;
break;
}
if (bx == null) {
ljEmpty = lj;
}
}
if (!bFound) {
if (ljEmpty != null) {
ljEmpty.setB(b);
} else {
OALeftJoin ljx = new OALeftJoin();
ljx.setA((A) valueA);
ljx.setB(b);
hubCombined.add(ljx);
}
}
}
private void remove(B b) {
OALeftJoin found = null;
for (OALeftJoin lj : hubCombined) {
B bx = (B) lj.getB();
if (bx == b) {
found = lj;
break;
}
}
if (found == null) {
return;
}
Object valueA = found.getA();
boolean bFoundAnother = false;
for (OALeftJoin lj : hubCombined) {
if (lj.getA() != valueA) {
continue;
}
B bx = (B) lj.getB();
if (bx != b) {
bFoundAnother = true;
break;
}
}
if (bFoundAnother) {
hubCombined.remove(found);
} else {
found.setB(null);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy