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

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

There is a newer version: 3.7.10
Show 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.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.logging.Logger;

import com.viaoa.object.OACascade;
import com.viaoa.object.OAFinder;
import com.viaoa.object.OALinkInfo;
import com.viaoa.object.OAObject;
import com.viaoa.object.OAObjectCacheDelegate;
import com.viaoa.object.OAObjectDSDelegate;
import com.viaoa.object.OAObjectDelegate;
import com.viaoa.object.OAObjectDeleteDelegate;
import com.viaoa.object.OAObjectInfo;
import com.viaoa.object.OAObjectInfoDelegate;
import com.viaoa.object.OAObjectPropertyDelegate;
import com.viaoa.object.OAObjectReflectDelegate;
import com.viaoa.object.OAObjectSaveDelegate;
import com.viaoa.object.OAThreadLocalDelegate;
import com.viaoa.sync.OASync;
import com.viaoa.sync.OASyncDelegate;
import com.viaoa.util.OACompare;
import com.viaoa.util.OAFilter;
import com.viaoa.util.OANullObject;

/**
 * Main delegate used for working with the Active Object for a Hub. All methods that have an "_" prefix should not be called directly, as
 * there is a calling method that should be used, that performs additional functionality. If a method does not have the "_" prefix and is
 * accessible, then it is ok to call it, but will most likely have a matching method name in the Hub class.
 *
 * @author vincevia
 */
public class HubDelegate {
	private static Logger LOG = Logger.getLogger(HubDelegate.class.getName());
	public static final Boolean TRUE = new Boolean(true);
	public static final Boolean FALSE = new Boolean(false);

	public static boolean getChanged(Hub thisHub, int iCascadeRule, OACascade cascade) {
		if (cascade.wasCascaded(thisHub, true)) {
			return false;
		}

		if (HubDataDelegate.getChanged(thisHub)) {
			return true;
		}
		if (iCascadeRule == OAObject.CASCADE_NONE) {
			return false;
		}

		if (thisHub.isOAObject()) {
			for (int i = 0;; i++) {
				Object object = HubDataDelegate.getObjectAt(thisHub, i);
				if (object == null) {
					break;
				}
				if (object instanceof OAObject) {
					OAObject obj = (OAObject) object;
					if (OAObjectDelegate.getChanged(obj, iCascadeRule, cascade)) {
						return true;
					}
				}
			}
		}
		return false;
	}

	/**
	 * Verifies that the property in obj is unique for all objects in this Hub (not in all of system). 
* Note: if OAObject and isLoading, then true is always returned.
* Note: if property value is a null or a blank String, then it is not checked. * * @return true if object is valid, false if another object already uses same unique property value. */ public static boolean verifyUniqueProperty(final Hub thisHub, final Object object) { if (thisHub == null || object == null) { return true; } if (object instanceof OAObject) { if (OAThreadLocalDelegate.isLoading()) { return true; } } Object object2; Method m = null; String uniqueLinkPropName; try { uniqueLinkPropName = thisHub.data.getUniqueProperty(); if (uniqueLinkPropName == null) { uniqueLinkPropName = thisHub.datam.getUniqueProperty(); } if (uniqueLinkPropName != null) { OAObjectInfo oi = thisHub.getOAObjectInfo(); if (oi.getLinkInfo(uniqueLinkPropName) == null) { uniqueLinkPropName = null; } } if (uniqueLinkPropName != null) { object2 = OAObjectPropertyDelegate.getProperty((OAObject) object, uniqueLinkPropName); } else { m = thisHub.data.getUniquePropertyGetMethod(); if (m == null) { m = thisHub.datam.getUniquePropertyGetMethod(); if (m == null) { return true; } } object2 = m.invoke(object, null); if (object2 == null) { return true; } if (object2 instanceof String && ((String) object2).equals("")) { return true; } } } catch (Exception e) { String s = m == null ? "" : m.getName(); throw new RuntimeException("Error invoking " + s, e); } for (int i = 0;; i++) { Object obj = thisHub.elementAt(i); if (obj == null) { break; } if (obj == object) { continue; } try { if (uniqueLinkPropName != null) { Object obj2 = OAObjectPropertyDelegate.getProperty((OAObject) obj, uniqueLinkPropName); if (OACompare.compare(obj2, object2) == 0) { return false; } continue; } Object obj2 = m.invoke(obj, null); if (obj2 == null) { continue; } if (obj2 == object2 || obj2.equals(object2)) { return false; } } catch (Exception e) { String s = m == null ? "" : m.getName(); throw new RuntimeException("Error invoking " + s, e); } } return true; } protected static Object getRealObject(Hub hub, Object object) { if (object != null && !object.getClass().equals(hub.getObjectClass())) { Object objx = OAObjectCacheDelegate.get(hub.getObjectClass(), object); if (objx != null) { return objx; } object = HubDataDelegate.getObject(hub, object); // might not have loaded all data yet (fetchMore will be called) } return object; } protected static String getPropertyPathforClasses(Hub hub, Class[] classes) { if (classes == null) { return null; } Class c = hub.getObjectClass(); String path = null; int x = classes.length; for (int i = 0; i < x; i++) { OAObjectInfo oi = OAObjectInfoDelegate.getOAObjectInfo(c); // this never returns null // find property to use List al = oi.getLinkInfos(); OALinkInfo liFound = null; for (int ii = 0; ii < al.size(); ii++) { OALinkInfo li = (OALinkInfo) al.get(ii); if (classes[i].equals(li.getToClass())) { if (li.getToClass() == null) { if (liFound != null) { continue; } } if (liFound != null) { throw new RuntimeException("more then one link for hubClass=" + c + ", find linkClass=" + classes[i]); } liFound = li; // if (li.getType() == li.ONE) break; // try to find ONE type, but will settle on MANY } } if (liFound == null) { return null; } if (path == null) { path = liFound.getName(); } else { path += "." + liFound.getName(); } c = classes[i]; } return path; } /** * Returns the OAObject that owns this Hub * * @see HubDetailDelegate#getDataMaster to get the sharedHub that has a DataMaster */ public static OAObject getMasterObject(Hub hub) { if (hub == null) { return null; } HubDataMaster dm = HubDetailDelegate.getDataMaster(hub, true); if (dm == null) { return null; } return dm.getMasterObject(); } /** * Returns the Class of OAObject that owns this Hub. */ public static Class getMasterClass(Hub hub) { if (hub == null) { return null; } HubDataMaster dm = HubDetailDelegate.getDataMaster(hub, true); Object obj = dm.getMasterObject(); if (obj != null) { return obj.getClass(); } if (dm.getMasterHub() != null) { return dm.getMasterHub().getObjectClass(); } return null; } /** * Set the Class of objects that this Hub will contain. *

* Note: you can not reset the Object class if there are any objects in it. * * @param objClass Class for the object being stored */ public static void setObjectClass(Hub thisHub, Class objClass) { if (thisHub.data.objClass != null && !thisHub.data.objClass.equals(objClass) && !thisHub.data.objClass.equals(OAObject.class)) { if (HubDataDelegate.getCurrentSize(thisHub) > 0 || (thisHub.datau.getVecHubDetail() != null && thisHub.datau.getVecHubDetail().size() > 0)) { throw new RuntimeException("cant change object class if objects are in hub"); } HubDataMaster dm = HubDetailDelegate.getDataMaster(thisHub); if (dm.getMasterHub() != null || thisHub.datam.getMasterObject() != null) { throw new RuntimeException("cant change object class if masterObject exists"); } if (thisHub.datau.getSharedHub() != null || HubShareDelegate.getSharedWeakHubSize(thisHub) > 0) { throw new RuntimeException("cant change object class since this is a shared hub."); } } // 20141111 removed since the select could be valid // HubSelectDelegate.cancelSelect(thisHub, true); thisHub.data.objClass = objClass; /* 20141111 not needed here if (objClass != null) { // find out if class is OAObject thisHub.data.setOAObjectFlag(OAObject.class.isAssignableFrom(objClass)); // thisHub.data.setObjectInfo(OAObjectInfoDelegate.getOAObjectInfo(objClass)); } else { thisHub.data.setObjectInfo(null); thisHub.data.setOAObjectFlag(false); } */ } /** * If this hub has a master Hub or link Hub and that Hub does not have an active Object set, then this Hub is invalid. */ public static boolean isValid(final Hub thisHub) { HubDataMaster dm = HubDetailDelegate.getDataMaster(thisHub, true); if (dm.getMasterHub() != null && dm.getMasterObject() == null) { return false; } // 20181119 reworked to check other hubs for hubWithLink Hub h = HubLinkDelegate.getHubWithLink(thisHub, true); if (h != null) { Hub hx = h.datau.getLinkToHub(); if (hx != null) { if (!HubDelegate.isValid(hx)) { return false; } if (hx.dataa.activeObject == null) { if (!h.datau.isAutoCreate()) { return false; } } } } if (thisHub.datau.getAddHub() != null) { return HubDelegate.isValid(thisHub.datau.getAddHub()); } return true; } /** * Current state of Hub, in case it's in the process of being updated, based on another event that changes a Hub that is somehow * connected to this Hub. *

* Example: when Hub.AO is changed, and the "ripple affect" with other Hub changes. A hub that is updated/changed might access another * Hub that has not been updated yet. This is because the thread that makes the change calls the listeners sequentially. */ public static enum HubCurrentStateEnum { InSync, DetailDisconectedFromMaster, DetailHubNotSameAsMasterObject, // caused when object/hubs are in flux (hub event that is calling listeners and changing linkages) HubMergerNotUpdated } // 20201201 /** * Check to see if a Hub is correctly linked, or if it is in mid-flight of being changed. *

* Example: when an event affects multiple listeners, that affect updating detail hubs, hubMergers, etc. *

* This will check that a Hub is currently pointing (shared) with the correct master object. Used when Hubs are shared, master/detail, * hubMerger, hubCopy, hubFilter, hubCombined. * * @param thisHub * @param hubNew if not null and the Hub is not InSync, then hubNew will be shared or populated with the correct current hub. * @param arrayList same as hubNew, but using an arrayList * @return level of status. */ public static HubCurrentStateEnum getCurrentState(final Hub thisHub, final Hub hubNew, final ArrayList alNew) { if (thisHub == null) { return HubCurrentStateEnum.InSync; } Hub hub = thisHub; Hub hubMaster; boolean bHasMaster = false; for (int i = 0;; i++, hub = hubMaster) { HubDataMaster dm = HubDetailDelegate.getDataMaster(hub, true); hubMaster = dm.getMasterHub(); if (hubMaster == null) { break; // check for hubMerger } bHasMaster = true; final Object objMaster = hubMaster.getAO(); if (objMaster == dm.getMasterObject()) { if (objMaster == null && thisHub.getSize() > 0) { return HubCurrentStateEnum.DetailDisconectedFromMaster; } continue; } if (i > 0) { return HubCurrentStateEnum.DetailDisconectedFromMaster; } if (objMaster != null && (hubNew != null || alNew != null)) { // find correct hub OALinkInfo li = dm.getDetailToMasterLinkInfo(); if (li != null) { Object value = li.getReverseLinkInfo().getValue(objMaster); if (value != null) { if (value instanceof Hub) { if (hubNew != null) { hubNew.setSharedHub((Hub) value); } if (alNew != null) { for (T objNext : ((Hub) value)) { alNew.add(objNext); } } } else { if (hubNew != null) { hubNew.add((T) value); } if (alNew != null) { alNew.add((T) value); } } } } } return HubCurrentStateEnum.DetailHubNotSameAsMasterObject; } // check to see if hub is derived from another Hub, and check it hub = HubShareDelegate.getMainSharedHub(hub); HubMerger hubMerger = null; HubCombined hubCombined = null; HubFilter hubFilter = null; HubListener[] hls = HubEventDelegate.getAllListeners(hub); if (hls != null) { for (HubListener hl : hls) { if (!(hl instanceof HubListenerAdapter)) { continue; } HubListenerAdapter hla = (HubListenerAdapter) hl; Object listener = hla.getListener(); if (listener instanceof HubMerger) { hubMerger = (HubMerger) hla.getListener(); Hub hubx = hubMerger.getCombinedHub(); if (hubx == hub) { break; } hubMerger = null; } else if (listener instanceof HubCombined) { hubCombined = (HubCombined) hla.getListener(); Hub hubx = hubCombined.getMasterHub(); if (hubx == hub) { break; } hubCombined = null; } else if (listener instanceof HubFilter) { hubFilter = (HubFilter) hla.getListener(); Hub hubx = hubFilter.getHub(); if (hubx == hub) { break; } hubFilter = null; } } } if (hubFilter != null) { Hub hubx = hubFilter.getMasterHub(); HubCurrentStateEnum hcs = getCurrentState(hubx, null, null); if (hcs == HubCurrentStateEnum.InSync) { return hcs; } if (hubNew == null && alNew == null) { return hcs; } Hub hubTemp = new Hub(); getCurrentState(hubx, hubTemp, null); for (Object objx : hubTemp) { if (!hubFilter.isUsed(objx)) { continue; } if (hubNew != null) { hubNew.add((T) objx); } if (alNew != null) { alNew.add((T) objx); } } } else if (hubCombined != null) { ArrayList al = hubCombined.getHubs(); if (al != null) { HubCurrentStateEnum hcs = null; for (Hub hubx : al) { hcs = getCurrentState(hubx, null, null); if (hcs != HubCurrentStateEnum.InSync) { break; } } if (hcs == null) { return HubCurrentStateEnum.InSync; } if (hubNew == null && alNew == null) { return hcs; } for (Hub hubx : al) { getCurrentState(hubx, hubNew, alNew); } return hcs; } } else if (hubMerger != null) { Hub hubx = hubMerger.getRootHub(); HubCurrentStateEnum hcs = getCurrentState(hubx, null, null); if (hcs == HubCurrentStateEnum.InSync) { if (!OAThreadLocalDelegate.isHubMergerChanging() && !hubMerger.isLoadingCombinedHub()) { return hcs; } } if (hubNew == null && alNew == null) { return HubCurrentStateEnum.HubMergerNotUpdated; } Hub hubTemp = new Hub(); getCurrentState(hubx, hubTemp, null); OAFinder finder = new OAFinder(hubMerger.getPath()); ArrayList al; if (hubMerger.getUseAll()) { al = finder.find(hubTemp); } else { // ?? not sure that AO will be set al = finder.find((OAObject) hubTemp.getAO()); } if (hubNew != null) { hubNew.add((List) al); } if (alNew != null) { alNew.addAll((List) al); } return HubCurrentStateEnum.HubMergerNotUpdated; } return HubCurrentStateEnum.InSync; } /** * created 20110904 Find the hub that controls whether or not this hub is valid. So that it can also be listened to, so that hub isValid * can be recalculated * * @return controlling hub, or param hub if there is no controlling hub */ public static Hub getControllingHub(Hub thisHub) { HubDataMaster dm = HubDetailDelegate.getDataMaster(thisHub, true); if (dm.getMasterHub() != null) { return dm.getMasterHub(); } // 20181119 find shared hub with link Hub hubWithLink = HubLinkDelegate.getHubWithLink(thisHub, true); if (hubWithLink != null && hubWithLink.datau.getLinkToHub() != null) { if (hubWithLink.datau.isAutoCreate()) { return getControllingHub(hubWithLink.datau.getLinkToHub()); } return hubWithLink.datau.getLinkToHub(); } if (thisHub.datau.getAddHub() != null) { return HubDelegate.getControllingHub(thisHub.datau.getAddHub()); } return thisHub; } /** * Returns this hub, or one of its shared Hubs, that has an addHub established. */ public static Hub getAnyAddHub(final Hub hub) { if (hub.getAddHub() != null) { return hub; } // 20120716 OAFilter filter = new OAFilter() { @Override public boolean isUsed(Hub h) { return h.getAddHub() != null; } }; Hub[] hubs = HubShareDelegate.getAllSharedHubs(hub, filter); // was: Hub[] hubs = HubShareDelegate.getAllSharedHubs(hub); for (int i = 0; i < hubs.length; i++) { if (hubs[i].getAddHub() != null) { return hubs[i]; } } return null; } /** * 20181211 removed, use hub.getLinkHub(true) Returns this or any shared hub that uses the same active object and is linked to another * Hub. public static Hub getAnyLinkHub(final Hub thisHub) { if (thisHub.getLinkHub() != null) return thisHub; // 20120716 OAFilter * filter = new OAFilter() { * * @Override public boolean isUsed(Hub h) { return (h.dataa == thisHub.dataa && h.getLinkHub() != null); } }; Hub[] hubs = * HubShareDelegate.getAllSharedHubs(thisHub, filter); //was: Hub[] hubs = HubShareDelegate.getAllSharedHubs(thisHub); for * (int i=0; i 0)) { bHasMethod = false; updateMany2ManyLinks(thisHub, dm); // update any link tables } } Object[] objs = HubDataDelegate.getRemovedObjects(thisHub); if (objs == null) { return; } for (int i = 0; i < objs.length; i++) { OAObject obj = (OAObject) objs[i]; if (obj.getNew()) { continue; // does not exist in DS } if (liRev != null && liRev.isOwner()) { if (dm.liDetailToMaster != null) { Object ox = OAObjectReflectDelegate.getProperty(obj, dm.liDetailToMaster.getName()); if (ox == null) { OAObjectDeleteDelegate.delete(obj, cascade); } } } else if (dm != null && dm.liDetailToMaster != null && bHasMethod) { Object ox = OAObjectReflectDelegate.getProperty(obj, dm.liDetailToMaster.getName()); if (ox == null) { // else property has been reassigned // 20120925 OAObjectDSDelegate.removeReference(obj, dm.liDetailToMaster); //was: OAObjectSaveDelegate._saveObjectOnly(obj, cascade); } } else if (bIsSaving && dm != null && dm.liDetailToMaster != null && !bHasMethod && OASync.isServer() && !obj.isDeleted()) { // 20181126 if it is a removed object from ServerRoot, need to save now OAObjectSaveDelegate.save(obj, iCascadeRule, cascade); } } } private static void updateMany2ManyLinks(Hub thisHub, HubDataMaster dm) { if (dm == null || dm.liDetailToMaster == null) { return; } OAObject[] adds = HubAddRemoveDelegate.getAddedObjects(thisHub); OAObject[] removes = HubAddRemoveDelegate.getRemovedObjects(thisHub); boolean b = false; // cross update opposite hub vecAdd/Remove for (int i = 0; adds != null && i < adds.length; i++) { b = true; if (!(adds[i] instanceof OAObject)) { continue; } OAObject obj = (OAObject) adds[i]; if (obj.getNew()) { continue; } Object objx = OAObjectReflectDelegate.getRawReference(obj, dm.liDetailToMaster.getName()); if (objx instanceof Hub) { HubDataDelegate.removeFromAddedList((Hub) objx, dm.getMasterObject()); } } for (int i = 0; removes != null && i < removes.length; i++) { b = true; if (!(removes[i] instanceof OAObject)) { continue; } OAObject obj = (OAObject) removes[i]; Object objx = OAObjectReflectDelegate.getRawReference(obj, dm.liDetailToMaster.getName()); if (objx instanceof Hub) { HubDataDelegate.removeFromRemovedList((Hub) objx, dm.getMasterObject()); } } if (b) { String propFromMaster = OAObjectInfoDelegate.getReverseLinkInfo(dm.liDetailToMaster).getName(); HubDSDelegate.updateMany2ManyLinks(dm.getMasterObject(), adds, removes, propFromMaster); } } public static void setUniqueProperty(Hub thisHub, String propertyName) { if (propertyName == null) { thisHub.data.setUniqueProperty(null); thisHub.data.setUniquePropertyGetMethod(null); return; } if (propertyName.indexOf('.') >= 0) { throw new IllegalArgumentException( "Property " + propertyName + " can only be for a property in " + thisHub.getObjectClass().getName()); } thisHub.data.setUniquePropertyGetMethod(OAObjectInfoDelegate.getMethod(thisHub.getObjectClass(), "get" + propertyName)); if (thisHub.data.getUniquePropertyGetMethod() == null) { throw new IllegalArgumentException("Get Method for Property " + propertyName + " not found"); } if (thisHub.data.getUniquePropertyGetMethod().getParameterTypes().length > 0) { throw new IllegalArgumentException("Get Method for Property " + propertyName + " expects parameters"); } thisHub.data.setUniqueProperty(propertyName); } /** * Used to update a property in each object to equal/store the position within this Hub. * * @param property is neme of property to update. * @param startNumber is number to begin numbering at. Default is 0, which will match the Hub position. * @param bKeepSeq, if false then seq numbers are not updated when an object is removed */ public static void setAutoSequence(Hub thisHub, String property, int startNumber, boolean bKeepSeq) { // 20091030 only set for server for detail hubs boolean bServerOnly = false; if (thisHub.getMasterObject() != null) { if (!HubCSDelegate.isServer(thisHub)) { return; // only set up for server } bServerOnly = true; } if (thisHub.data.getAutoSequence() != null) { thisHub.data.getAutoSequence().close(); } thisHub.cancelSort(); // 20090801 need to remove any sorters thisHub.data.setAutoSequence(new HubAutoSequence(thisHub, property, startNumber, bKeepSeq, bServerOnly)); } public static HubAutoSequence getAutoSequence(Hub thisHub) { return thisHub.data.getAutoSequence(); } public static void resequence(Hub thisHub) { if (thisHub.data.getAutoSequence() != null) { thisHub.data.getAutoSequence().resequence(); } } /** * Makes sure that for each object in a hubMaster, there exists an object in this hub where property is equal to the hubMaster object. * * @param hubMaster hub with list of object * @param property Property in this hubs objects that match object type in hubMaster */ public static void setAutoMatch(Hub thisHub, String property, Hub hubMaster, boolean bServerSideOnly) { if (thisHub.data.getAutoMatch() != null) { thisHub.data.getAutoMatch().close(); } // 20220802 now works with Enum (name/value) property // if (hubMaster != null) { HubAutoMatch am = new HubAutoMatch(); thisHub.data.setAutoMatch(am); am.setServerSideOnly(bServerSideOnly); am.init(thisHub, property, hubMaster); // } } public static HubAutoMatch getAutoMatch(Hub thisHub) { return thisHub.data.getAutoMatch(); } public static int getSize(Hub thisHub) { if (HubSelectDelegate.isMoreData(thisHub)) { if (!HubSelectDelegate.isCounted(thisHub)) { if (HubDataDelegate.getCurrentSize(thisHub) == 0) { HubSelectDelegate.fetchMore(thisHub); // see if this will load it, before calling count on the select if (!HubSelectDelegate.isMoreData(thisHub)) { return getSize(thisHub); } } } int x = HubSelectDelegate.getCount(thisHub); if (x > 0) { return x; } } return HubDataDelegate.getCurrentSize(thisHub); } /** */ public static int getLoadedSize(Hub thisHub) { if (thisHub == null) { return 0; } thisHub.loadAllData(); return getSize(thisHub); } private static int cntLoadedSizeError; protected static void setProperty(Hub thisHub, String name, Object obj) { if (name == null) { return; } name = name.toUpperCase(); if (thisHub.data.getHashProperty() == null) { thisHub.data.setHashProperty(new Hashtable(7)); } thisHub.data.getHashProperty().put(name, (obj == null) ? OANullObject.instance : obj); } protected static Object getProperty(Hub thisHub, String name) { if (thisHub.data.getHashProperty() == null) { return null; } name = name.toUpperCase(); Object obj = thisHub.data.getHashProperty().get(name); if (obj instanceof OANullObject) { obj = null; } return obj; } protected static void removeProperty(Hub thisHub, String name) { if (thisHub.data.getHashProperty() != null) { name = name.toUpperCase(); thisHub.data.getHashProperty().remove(name); } } // 20141030 public static void setReferenceable(Hub hub, boolean bReferenceable) { if (hub == null) { return; } if (!OASyncDelegate.isServer(hub)) { return; } OAObjectInfo oi = OAObjectInfoDelegate.getOAObjectInfo(hub.getObjectClass()); if (!OAObjectInfoDelegate.isWeakReferenceable(oi)) { return; } boolean bSupportStorage = oi.getSupportsStorage(); Object master = HubDelegate.getMasterObject(hub); if (!(master instanceof OAObject)) { return; } OALinkInfo li = HubDetailDelegate.getLinkInfoFromDetailToMaster(hub); if (li == null) { return; } OALinkInfo liRev = li.getReverseLinkInfo(); if (liRev == null) { return; } if (liRev.getCacheSize() > 0) { if (bReferenceable || bSupportStorage) { boolean b = OAObjectPropertyDelegate.setPropertyWeakRef((OAObject) master, liRev.getName(), !bReferenceable, hub); if (!b) { return; // already done, dont need to check/change parents } } } if (bReferenceable) { // make parents referenceable OAObjectPropertyDelegate.setReferenceable((OAObject) master, bReferenceable); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy