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

com.viaoa.object.OAObjectEventDelegate 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.object;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.viaoa.remote.multiplexer.OARemoteThreadDelegate;
import com.viaoa.sync.OASync;
import com.viaoa.sync.OASyncDelegate;
import com.viaoa.hub.*;
import com.viaoa.undo.OAUndoManager;
import com.viaoa.undo.OAUndoableEdit;
import com.viaoa.util.OAFilter;
import com.viaoa.util.OANotExist;
import com.viaoa.util.OANullObject;
import com.viaoa.util.OAString;
import com.viaoa.util.OAThrottle;


public class OAObjectEventDelegate {

    private static Logger LOG = Logger.getLogger(OAObjectEventDelegate.class.getName());
    private static final String WORD_CHANGED = "CHANGED";
    
    private static long msThrottle;
    private static int cntError;
    
    /**
	    Used to manage property changes.
	    Sends a "hubPropertyChange()" to all listeners of the Hubs that this object is a member of.  
*/ protected static void fireBeforePropertyChange(final OAObject oaObj, final String propertyName, Object oldObj, final Object newObj, final boolean bLocalOnly, final boolean bSetChanged) { if (oaObj == null || propertyName == null) return; if (oldObj == newObj) return; if (oldObj != null && oldObj.equals(newObj)) return; final boolean bIsLoading = OAThreadLocalDelegate.isLoading(); if (bIsLoading) { if (!OAObjectHubDelegate.isInHub(oaObj)) { // 20110719: could be in the OAObjectCache.SelectAllHubs // no listeners, need to load quick as possible if (OASyncDelegate.isServer(oaObj)) { // 20150604 if client, then it needs to send prop change to server return; } if (OAObjectCSDelegate.isInNewObjectCache(oaObj)) { // 20160212 created on client, has not been sent to server yet return; } } } else if (!OARemoteThreadDelegate.isRemoteThread()) { // 20180617 validate boolean bSkip = false; if (propertyName != null) { bSkip = OAObjectDelegate.WORD_Changed.equalsIgnoreCase(propertyName); bSkip = bSkip || OAObjectDelegate.WORD_New.equalsIgnoreCase(propertyName); bSkip = bSkip || OAObjectDelegate.WORD_Deleted.equalsIgnoreCase(propertyName); } if (!bSkip && !bIsLoading) { OAObjectEditQuery em = OAObjectEditQueryDelegate.getVerifyPropertyChangeEditQuery(oaObj, propertyName, oldObj, newObj); if (!em.getAllowed() || em.getThrowable() != null) { String msg = em.getResponse(); if (em.getThrowable() != null) { msg = OAString.concat(msg, "Exception: "+em.getThrowable().getMessage(), ", "); } else if (OAString.isEmpty(msg)) msg = "Invalid property value, property="+propertyName+", value="+newObj; else if (!em.getAllowed()) { if (msg == null) msg = ""; else msg = ". Reason: " + msg; msg = (oaObj.getClass().getSimpleName())+"."+propertyName+" change not allowed, value="+newObj + msg; } long ms = System.currentTimeMillis(); ++cntError; if (ms > msThrottle + 5000) { LOG.warning(cntError+") " + msg+", will continue without throwing an exception"); msThrottle = ms; } /** 20181018, 20190502 dont throw an exception until there is more confidence. throw new RuntimeException(msg, em.getThrowable()); */ } } } // check to see if it is actually changed if (oldObj != null) { if (OAObjectReflectDelegate.getPrimitiveNull(oaObj, propertyName) || oldObj instanceof OANullObject) oldObj = null; } // verify that change is permitted // verify if recursive link that new parent is allowed OAObjectInfo oi = OAObjectInfoDelegate.getOAObjectInfo(oaObj); final String propertyU = propertyName.toUpperCase(); OALinkInfo linkInfo = OAObjectInfoDelegate.getLinkInfo(oi, propertyU); OALinkInfo toLinkInfo; if (linkInfo != null) toLinkInfo = OAObjectInfoDelegate.getReverseLinkInfo(linkInfo); else toLinkInfo = null; if (toLinkInfo != null && toLinkInfo.bRecursive) { OALinkInfo liRecursive = OAObjectInfoDelegate.getRecursiveLinkInfo(oi, OALinkInfo.ONE); // ex: "ParentSection" if (liRecursive == linkInfo) { // parent property changed. ex: "setParentSection" // verify that it can be placed if (newObj != null) { if (oaObj == newObj) { // object cant be its own parent throw new RuntimeException("Can not set the Parent to itself"); } // cant assign a child of this object as the new parent - causes orphaned objects for (Object obj=newObj; ;) { obj = OAObjectReflectDelegate.getProperty((OAObject)obj, liRecursive.getName()); if (obj == null) break; if (obj == oaObj) { OAObjectReflectDelegate.setProperty(oaObj, linkInfo.getName(), oldObj, null); throw new RuntimeException("Can not assign Parent to a Child");// causes orphans } } } } } // 20151205 check to see if owner is being reassigned if (linkInfo != null && oldObj != null && newObj != null && !oaObj.isNew() && linkInfo.getType() == OALinkInfo.ONE && !linkInfo.getCalculated()) { OALinkInfo revLinkInfo = OAObjectInfoDelegate.getReverseLinkInfo(linkInfo); if (revLinkInfo != null && revLinkInfo.getOwner()) { String s = "FYI (no exception), owner is being reassigned, object="+oaObj.getClass().getSimpleName()+", property="+propertyName+", new value="+newObj; RuntimeException e = new RuntimeException(s); LOG.log(Level.FINE, s, e); // throw e; } } // 20170420 check to see if owner is being reassigned to null if (linkInfo != null && oldObj instanceof OAObject && newObj == null && !oaObj.isDeleted() && !oaObj.isNew() && linkInfo.getType() == OALinkInfo.ONE && !linkInfo.getCalculated()) { if (!OAThreadLocalDelegate.isDeleting() && OASync.isServer()) { OAObjectInfo oix = OAObjectInfoDelegate.getOAObjectInfo((OAObject)oldObj); if (!oix.getLookup() && !oix.getPreSelect()) { cntSetOwnerNull++; if (throttleSetOwnerNull.check()) { String s = "FYI (no exception), reference is being set to null, object="+oaObj.getClass().getSimpleName()+", property="+propertyName+", new value="+newObj+", old value="+oldObj; RuntimeException e = new RuntimeException(s); LOG.log(Level.FINE, "cnt="+(cntSetOwnerNull)+" " + s, e); } } } } if (linkInfo == null && !OARemoteThreadDelegate.isRemoteThread()) { OAPropertyInfo propInfo = OAObjectInfoDelegate.getPropertyInfo(oi, propertyU); if (propInfo != null) { if (propInfo.getId() && !OAObjectDSDelegate.isAssigningId(oaObj)) { String s = OAObjectKeyDelegate.verifyKeyChange(oaObj); if (s != null) { throw new RuntimeException(s); } } if (propInfo.getUnique() && newObj != null && !OAObjectDSDelegate.isAssigningId(oaObj)) { // 20180629 OAObject obj = OAObjectUniqueDelegate.getUnique(oaObj.getClass(), propertyName, newObj, false); if (obj != null && obj != oaObj) { throw new RuntimeException("property is unique, and value already assigned to another object. Class="+oaObj.getClass().getSimpleName()+", property="+propertyName+", value="+newObj); } /*was: OAFilter filter = new OAFilter() { public boolean isUsed(OAObject obj) { Object objx = obj.getProperty(propertyU); if (objx == null) return false; return objx.equals(newObj); } }; OADataSource ds = OADataSource.getDataSource(oaObj.getClass(), filter); if (ds != null && (!(ds instanceof OADataSourceObjectCache))) { Iterator it = ds.select(oaObj.getClass(), propertyU+" = ?", new Object[] {newObj}, null, null, null, null, 2, filter, false); try { for ( ;it != null && it.hasNext(); ) { Object objx = it.next(); if (objx != oaObj) { throw new RuntimeException("property is unique, and value is assigned to another object."); } } } finally { if (it != null) it.remove(); } } else if (!propInfo.getId()) { Object objLast = null; for (;;) { Object objx = OAObjectCacheDelegate.findNext(objLast, oaObj.getClass(), propertyU, newObj); if (objx == null) break; if (objx != oaObj) { throw new RuntimeException("property is unique, and value is assigned to another object."); } objLast = objx; } } */ } } } if (!bIsLoading) { sendHubBeforePropertyChange(oaObj, propertyName, oldObj, newObj); } if (!bLocalOnly && !bIsLoading) { // 20140314 if it is in newObjectCache (this computer only), then dont send prop changes if (!OAObjectCSDelegate.isInNewObjectCache(oaObj)) { OAObjectCSDelegate.fireBeforePropertyChange(oaObj, propertyName, oldObj, newObj); } } } //qqqqqq private static final OAThrottle throttleSetOwnerNull = new OAThrottle(500); private static int cntSetOwnerNull; /** Used to manage property changes. This will: 1: update null property information for primitive property types 2: update the objectKey, which would then update the ObjectCache 3: update object hubs if this is a reference property change 4: Send "hubPropertyChange()" to all listeners of the Hubs that this object is a member of. 5: Send event to Server. see OAThreadLocalDelegate#setSuppressFirePropertyChange(boolean) to suppress this method from running by the current thread. */ protected static void firePropertyChange(final OAObject oaObj, final String propertyName, Object oldObj, Object newObj, boolean bLocalOnly, boolean bSetChanged) { firePropertyChange(oaObj, propertyName, oldObj, newObj, bLocalOnly, bSetChanged, false); } protected static void firePropertyChange(final OAObject oaObj, final String propertyName, Object oldObj, Object newObj, boolean bLocalOnly, boolean bSetChanged, boolean bUnknownValues) { if (oaObj == null || propertyName == null) return; String propertyU = propertyName.toUpperCase(); OAObjectInfo oi = OAObjectInfoDelegate.getOAObjectInfo(oaObj); if (oldObj != null) { if (OAObjectReflectDelegate.getPrimitiveNull(oaObj, propertyU) || oldObj instanceof OANullObject) oldObj = null; } // note: a primitive null can only be set by calling OAObjectReflectDelegate.setProperty(...) if (newObj instanceof OANullObject) newObj = null; if (newObj != null) { OAObjectReflectDelegate.removePrimitiveNull(oaObj, propertyU); } else { // 20121001 for byte[] props OAObjectReflectDelegate.setPrimitiveNull(oaObj, propertyU); } if (oldObj instanceof OANullObject) oldObj = null; OALinkInfo linkInfo = OAObjectInfoDelegate.getLinkInfo(oi, propertyU); boolean bWasEmpty = false; if (linkInfo != null && oldObj == null) { // oldObj might never have been loaded before setMethod was called, which will have the oldValue=null - // need to check in oaObj.properties to see what orig value was. oldObj = OAObjectPropertyDelegate.getProperty(oaObj, propertyName, true, true); if (oldObj == OANotExist.instance) { bWasEmpty = true; oldObj = null; } } Object origOldObj = oldObj; if (oldObj instanceof OAObjectKey) { boolean b = false; if (newObj instanceof OAObject) { if (OAObjectKeyDelegate.getKey((OAObject)newObj).equals(oldObj)) { oldObj = newObj; b = true; } } if (!b) { Object objx = OAObjectCacheDelegate.get(linkInfo.toClass, (OAObjectKey)oldObj); if (objx != null) oldObj = objx; } } if (!bUnknownValues) { if (oldObj == newObj && !bWasEmpty) return; if (oldObj != null && oldObj.equals(newObj)) return; } OAPropertyInfo propInfo = null; OACalcInfo calcInfo = null; if (linkInfo == null) { propInfo = OAObjectInfoDelegate.getPropertyInfo(oi, propertyU); if (propInfo == null) { calcInfo = OAObjectInfoDelegate.getOACalcInfo(oi, propertyU); } } OAObjectKey origKey; if (propInfo != null && propInfo.getId()) { origKey = OAObjectKeyDelegate.getKey(oaObj, oldObj); // make sure key uses the prevId, so that it can be found on other computers OAObjectKeyDelegate.updateKey(oaObj, true); // this will make sure that it is a valid (unique) value } else { origKey = OAObjectKeyDelegate.getKey(oaObj); } if (linkInfo != null){ // must update ref properties before sending events // 20110314: need to store nulls, so that it wont go back to server everytime OAObjectPropertyDelegate.setPropertyCAS(oaObj, propertyName, newObj, origOldObj, bWasEmpty, false); } else { // 20130318 if (propInfo != null && propInfo.isBlob()) { OAObjectPropertyDelegate.setPropertyCAS(oaObj, propertyName, newObj, origOldObj, bWasEmpty, false); } } boolean bChangeHold = oaObj.changedFlag; boolean bIsChangeProp = WORD_CHANGED.equals(propertyU); if (!bIsChangeProp) oaObj.changedFlag = true; // 20100406 boolean bIsLoading = OAThreadLocalDelegate.isLoading(); if (!bIsLoading) { OAObjectKey key = OAObjectKeyDelegate.getKey(oaObj); Object objOld = oldObj; if (objOld instanceof OAObject) { objOld = OAObjectKeyDelegate.getKey((OAObject)objOld); } Object objNew = newObj; if (objNew instanceof OAObject) { objNew = OAObjectKeyDelegate.getKey((OAObject)objNew); } /* Object oldx; if (objOld instanceof byte[]) { oldx = "byte[" + ((byte[])objOld).length +"]"; } else oldx = objOld; */ /* Object newx; if (objNew instanceof byte[]) { newx = "byte[" + ((byte[])objNew).length +"]"; } else newx = objNew; String s = String.format("Change, class=%s, id=%s, property=%s, oldValue=%s, newVaue=%s", OAString.getClassName(oaObj.getClass()), key.toString(), propertyName, OAConv.toString(oldx), OAConv.toString(newx) ); if (oi.bUseDataSource) { // 20120429 if (calcInfo == null) { if (linkInfo == null || !linkInfo.bCalculated) { OAObject.OALOG.fine(s); } } } LOG.fine(s); */ if (!bLocalOnly) { // prior to 20100406, this was always calling these methods OARemoteThreadDelegate.startNextThread(); // if this is OAClientThread, so that OAClientMessageHandler can continue with next message //note: this next method will just return, since fireBeforePropChange is now doing this // OAObjectCSDelegate.fireAfterPropertyChange(oaObj, origKey, propertyName, oldObj, newObj); } } if (!bIsLoading) { // 20110603 add support for creating undoable events if oaThreadLocal.createUndoablePropertyChanges=true // default=false, which means that the individual UI components are controlling this if (OAThreadLocalDelegate.getCreateUndoablePropertyChanges()) { if (OAUndoManager.getUndoManager() != null) { OAUndoableEdit ue = OAUndoableEdit.createUndoablePropertyChange("", oaObj, propertyName, oldObj, newObj); OAUndoManager.add(ue); } } } // 20151117 if one2one, and new value is null, then set prop to null in link prop if (linkInfo != null){ OALinkInfo revLinkInfo = OAObjectInfoDelegate.getReverseLinkInfo(linkInfo); if (revLinkInfo != null) { if (revLinkInfo.type == OALinkInfo.ONE) { if (oldObj instanceof OAObjectKey) { if (OASync.isClient(oaObj)) { // 20151117 dont get from server if this is client Object objx = OAObjectCacheDelegate.get(linkInfo.toClass, (OAObjectKey)oldObj); if (objx instanceof OAObject) OAObjectPropertyDelegate.setPropertyCAS((OAObject)objx, revLinkInfo.getName(), null, oaObj); } } } } } // Note: this needs to be ran even if isSuppressingEvents(), it wont send messages but it might need to update detail hubs if (!bIsLoading) { if (OAObjectHubDelegate.isInHub(oaObj)) { sendHubPropertyChange(oaObj, propertyName, oldObj, newObj, linkInfo); } OAObjectCacheDelegate.fireAfterPropertyChange(oaObj, origKey, propertyName, oldObj, newObj, bLocalOnly, true); if (propInfo != null && propInfo.isNameValue()) { if (OAObjectHubDelegate.isInHub(oaObj)) { sendHubPropertyChange(oaObj, propertyName+"AsString", oldObj, newObj, linkInfo); } OAObjectCacheDelegate.fireAfterPropertyChange(oaObj, origKey, propertyName+"AsString", oldObj, newObj, bLocalOnly, true); } } oaObj.changedFlag = bChangeHold; /*was: moved to below // 20160304 if (!bIsLoading) { if (oi.getHasTriggers()) { HubEvent hubEvent = new HubEvent(oaObj, propertyName, oldObj, newObj); try { OAThreadLocalDelegate.addHubEvent(hubEvent); oi.onChange(oaObj, propertyName, hubEvent); } finally { OAThreadLocalDelegate.removeHubEvent(hubEvent); } } } */ // set to Changed if (!bIsChangeProp && bSetChanged && !bChangeHold && (calcInfo == null)) { if (!oaObj.isChanged()) { if (linkInfo == null || !linkInfo.bCalculated) { // 20120429 try { OAThreadLocalDelegate.setSuppressCSMessages(true); // the client will setChanged when it gets the propertyChange message oaObj.setChanged(true); } finally { OAThreadLocalDelegate.setSuppressCSMessages(false); } } } } if (linkInfo != null) { updateLink(oaObj, oi, linkInfo, oldObj, newObj); } // 20181126 moved from above if (!bIsLoading) { if (oi.getHasTriggers()) { HubEvent hubEvent = new HubEvent(oaObj, propertyName, oldObj, newObj); try { OAThreadLocalDelegate.addHubEvent(hubEvent); oi.onChange(oaObj, propertyName, hubEvent); } finally { OAThreadLocalDelegate.removeHubEvent(hubEvent); } } } } protected static void sendHubBeforePropertyChange(OAObject oaObj, String propertyName, Object oldObj, Object newObj) { Hub[] hubs = OAObjectHubDelegate.getHubReferences(oaObj); if (hubs == null) return; for (Hub h : hubs) { if (h != null) HubEventDelegate.fireBeforePropertyChange(h, oaObj, propertyName, oldObj, newObj); } } public static void sendHubPropertyChange(final OAObject oaObj, final String propertyName, final Object oldObj, final Object newObj, final OALinkInfo linkInfo) { // Note: don't add this, HubEventDelegate will do it after it updates detail hubs: // if (OAObjectFlagDelegate.isSuppressingPropertyChangeEvents()) return; // Note: oldObj could be OAObjectKey Hub[] hubs = OAObjectHubDelegate.getHubReferences(oaObj); if (hubs == null) return; for (Hub h : hubs) { if (h != null) HubEventDelegate.fireAfterPropertyChange(h, oaObj, propertyName, oldObj, newObj, linkInfo); } /* 20101218 replaced by HubListenerTree // Check to see if a Calculated property is changed. / * how do properties from other link object notify this objects calc objects? Answer: when you add a HubListener to Hub, it will create detail hub and listeners and send calcPropertyChange event @see Hub#addHubListener(HubListener hl, String property) { this code here will check for property changes within this object and determine if it affects a calc property * / // see if the property change affects a Calc property OAObjectInfo oi = OAObjectInfoDelegate.getOAObjectInfo(oaObj); ArrayList al = oi.getCalcInfos(); for (int i=0; i < al.size(); i++) { OACalcInfo ci = (OACalcInfo) al.get(i); if (ci.getListenerCount() == 0) continue; // set by HubEventDelegate.addHubListener(..., property) when a calc property is being used and prop changes need to be checked (here). String[] s = ci.properties; for (int j=0; s != null && j < s.length; j++) { if (propertyName.equalsIgnoreCase(s[j])) { for (j=0; j This will move this object out of one Hub and into another when a property is changed.
This will also manage changes that involve recursive relationships.

Example: if the dept for an emp is changed, then the emp will be taken out of the orig dept.hubEmp hub and put into the new dept hubEmp */ private static void updateLink(final OAObject oaObj, OAObjectInfo oi, OALinkInfo linkInfo, Object oldObj, Object newObj) { // NOTE: oldObj could be OAObjectKey // taken out, since it will set OAClientThread.status = STATUS_FinishingAsServer // if (!OAClientDelegate.processIfServer()) return; // only process on server, and send events to clients (even if this is OAThreadClient) OALinkInfo revLinkInfo = OAObjectInfoDelegate.getReverseLinkInfo(linkInfo); if (revLinkInfo == null) return; Object obj; // 20160426 make sure that it has not changed obj = OAObjectPropertyDelegate.getProperty(oaObj, linkInfo.name); if (obj != newObj) { return; } if (revLinkInfo.type == OALinkInfo.ONE) { try { OAObjectInfo oiRev = OAObjectInfoDelegate.getOAObjectInfo(linkInfo.toClass); Method m = OAObjectInfoDelegate.getMethod(oiRev, "get"+revLinkInfo.name, 0); // make sure that the method exists if (m != null) { if (oldObj instanceof OAObjectKey) { if (OASync.isClient(oaObj)) { // 20151117 dont get from server if this is client oldObj = OAObjectCacheDelegate.get(linkInfo.toClass, (OAObjectKey)oldObj); } else { oldObj = OAObjectReflectDelegate.getObject(linkInfo.toClass, (OAObjectKey)oldObj); } } if (oldObj != null) { // 20150820 if one2one, then dont load if null and isClient // this was discovered when deleting an IDL and function/gsmrFunction (1to1) kept going to server for other value boolean b = true; if (OASync.isClient(oaObj)) { obj = OAObjectPropertyDelegate.getProperty((OAObject)oldObj, revLinkInfo.name); if (obj == null) { // dont get from server b = false; } } if (b) { obj = OAObjectReflectDelegate.getProperty((OAObject)oldObj, revLinkInfo.name); if (obj == oaObj) { OAObjectReflectDelegate.setProperty((OAObject)oldObj, revLinkInfo.name, null, null); } } } if (newObj != null) { // 20170411 if (revLinkInfo.getOwner()) { OAObjectPropertyDelegate.setPropertyCAS((OAObject) newObj, revLinkInfo.name, oaObj, null); OAObjectReflectDelegate.setProperty((OAObject)newObj, revLinkInfo.name, oaObj, null); } else { //was obj = OAObjectReflectDelegate.getProperty((OAObject)newObj, revLinkInfo.name); if (obj != oaObj) { OAObjectReflectDelegate.setProperty((OAObject)newObj, revLinkInfo.name, oaObj, null); } } } } } catch (Exception e) { } return; } if (revLinkInfo.type != OALinkInfo.MANY) return; Hub hub; boolean bUpdateHub = false; // 20131009 each link now has its own recursive flag OALinkInfo liRecursive; if (revLinkInfo.bRecursive) { liRecursive = OAObjectInfoDelegate.getRecursiveLinkInfo(oi, OALinkInfo.ONE); // ex: "ParentSection" } else liRecursive = null; //was: OALinkInfo liRecursive = OAObjectInfoDelegate.getRecursiveLinkInfo(oi, OALinkInfo.ONE); // ex: "ParentSection" boolean bOldIsKeyOnly = (oldObj instanceof OAObjectKey); // find all Hubs using this as the active object. // By changing a reference property, the object could be moved to another hub ArrayList alUpdateHub = null; if (oldObj != null || liRecursive != null) { Hub[] hubs = OAObjectHubDelegate.getHubReferences(oaObj); if (hubs != null) { for (Hub h : hubs) { if (h == null) continue; // 20120716 OAFilter filter = new OAFilter() { @Override public boolean isUsed(Hub h) { return (h.getAO() == oaObj); } }; Hub[] hubss = HubShareDelegate.getAllSharedHubs(h, filter); //was:Hub[] hubss = HubShareDelegate.getAllSharedHubs(h); for (int ii=0; ii(); alUpdateHub.add(hub); } } } } } /* recursive hub logic See if recursive hub ex: Section.setCatalog(catalog) or Section.setParentSection(section) This: "Section" Changed Prop: "Catalog" or "ParentSection" linkInfo: from Section -> Catalog or ParentSection toLinkInfo: = from Catalog or ParentSection -> Sections liRecursive = "ParentSection" Note: all recursive objects all assigned to the same owner object as the root hub. ex: all sections under a Catalog have Catalog assigned to it. This allows for queries to find all sections for a catalog To find all root (top level) sections for a catalog, select sections without a parentSection assigned */ if (liRecursive != null) { // if recursive if (revLinkInfo.getOwner() && linkInfo != liRecursive) { // owner property changed. ex: "Catalog" // need to update all recursive objects under this one. ex: "hubSections.section.catalog = catalog" obj = OAObjectReflectDelegate.getProperty(oaObj, OAObjectInfoDelegate.getReverseLinkInfo(liRecursive).getName()); // hubSections if (!(obj instanceof Hub)) throw new RuntimeException("OAObject.updateLink() method for recursive link not returning a Hub."); hub = (Hub) obj; for (int i=0; ;i++) { obj = hub.elementAt(i); // section if (obj == null) break; if (OAObjectReflectDelegate.getProperty((OAObject)obj, linkInfo.getName()) != newObj) { OAObjectReflectDelegate.setProperty((OAObject)obj, linkInfo.getName(), newObj, null); // setCatalog. This will set all of its recursive children } } obj = OAObjectReflectDelegate.getProperty(oaObj, liRecursive.getName()); // get parent (section) if (obj != null) { obj = OAObjectReflectDelegate.getProperty((OAObject)obj, linkInfo.getName()); // catalog if (obj == newObj) newObj = null; // otherwise, this object will be added to the rootHub else { // set Parent to null 2003/09/21 OAObjectReflectDelegate.setProperty(oaObj, liRecursive.getName(), null, null); // set ParentSection = null } } } else { if (liRecursive == linkInfo) { // parent property changed. ex: "setParentSection" // verfy that it can be placed if (newObj != null) { if (oaObj == newObj) { // object cant be its own parent if (bOldIsKeyOnly) { bOldIsKeyOnly = false; oldObj = OAObjectReflectDelegate.getObject(linkInfo.toClass, (OAObjectKey)oldObj); } OAObjectReflectDelegate.setProperty(oaObj, linkInfo.getName(), oldObj, null); throw new RuntimeException("Can not set the Parent to Itself"); } // cant assign a child of this object as the new parent - causes orphaned objects for (obj=newObj; ;) { obj = OAObjectReflectDelegate.getProperty((OAObject)obj, liRecursive.getName()); if (obj == null) break; if (obj == oaObj) { if (bOldIsKeyOnly) { bOldIsKeyOnly = false; oldObj = OAObjectReflectDelegate.getObject(linkInfo.toClass, (OAObjectKey)oldObj); } OAObjectReflectDelegate.setProperty(oaObj, linkInfo.getName(), oldObj, null); throw new RuntimeException("Can not assign Parent to a Child");// causes orphans } } } // find owner link boolean bOwned = false; OALinkInfo linkOwner = OAObjectInfoDelegate.getLinkToOwner(oi); // link to catalog OALinkInfo liRev = null; if (linkOwner != null) liRev = OAObjectInfoDelegate.getReverseLinkInfo(linkOwner); if (liRev != null && liRev.type == OALinkInfo.MANY) { bOwned = true; if (newObj == null) { // parentSection = null // if being set to null, then add to root hub. // if it was removed from old hub, then dont add to root hub boolean bAdd = !OAThreadLocalDelegate.isDeleting(oaObj); if (bAdd && !bOldIsKeyOnly && OAObjectReflectDelegate.isReferenceHubLoadedAndNotEmpty((OAObject)oldObj, revLinkInfo.getName())) { hub = (Hub) OAObjectReflectDelegate.getProperty((OAObject)oldObj, revLinkInfo.getName()); // Catalog.sections (original hub that this objects belonged to) bAdd = hub.contains(oaObj); } if (bAdd) { obj = OAObjectReflectDelegate.getProperty(oaObj, linkOwner.getName()); // Catalog if (obj != null) { Object obj2 = OAObjectReflectDelegate.getProperty((OAObject)obj, liRev.getName()); // catalog.hubSection if (!(obj2 instanceof Hub)) { throw new RuntimeException("OAObject.updateLink() method for recursive link owner not returning a Hub."); } hub = (Hub) obj2; if (hub.getObject(oaObj) == null) hub.add(oaObj); } } } else { // make sure owner is set for this object. this.catalog = ((Section)newObj).catalog obj = OAObjectReflectDelegate.getProperty((OAObject)newObj, linkOwner.getName()); if (OAObjectReflectDelegate.getProperty(oaObj, linkOwner.getName()) != obj) { OAObjectReflectDelegate.setProperty(oaObj, linkOwner.getName(), obj, null); // setCatalog (this will also set child recursive objects) } if (oldObj == null) { // remove from root hub, it is now assigned a parentSection obj = OAObjectReflectDelegate.getProperty(oaObj, linkOwner.getName()); // Catalog if (obj != null) { obj = OAObjectReflectDelegate.getProperty((OAObject) obj, liRev.getName()); // catalog.catalogSections if (!(obj instanceof Hub)) { throw new RuntimeException("OAObject.updateLink() method for recursive link owner not returning a Hub."); } hub = (Hub) obj; // catalog.catalogSections HubAddRemoveDelegate.remove(hub, oaObj, false, true, false, true, false, false); } } } } if (!bOwned) { Hub h = OAObjectInfoDelegate.getRootHub(oi); if (h != null) { if (oldObj == null) { // take out of unowned root hubs h.remove(oaObj); } else if (newObj == null) { // add to unowned root hubs // if it was removed from old hub, then dont add to root hub boolean bAdd = true; if (oldObj != null && !bOldIsKeyOnly && OAObjectReflectDelegate.isReferenceHubLoaded((OAObject)oldObj,revLinkInfo.getName())) { hub = (Hub) OAObjectReflectDelegate.getProperty((OAObject)oldObj, revLinkInfo.getName()); // Catalog.sections (original hub that this objects belonged to) bAdd = hub.contains(oaObj); } if (bAdd && h.getObject(oaObj) == null) { h.add(oaObj); } } } } } } } // end of recursive logic if (oldObj != null && !bOldIsKeyOnly) { try { if (OAObjectCSDelegate.isServer(oaObj) || OAObjectReflectDelegate.isReferenceHubLoaded((OAObject)oldObj, revLinkInfo.getName())) { obj = OAObjectReflectDelegate.getProperty((OAObject)oldObj, revLinkInfo.getName()); if (obj instanceof Hub) { Hub h = (Hub) obj; if (h.contains(oaObj)) h.remove(oaObj); } } } catch (Exception e) { } } if (newObj != null) { try { if (OAObjectCSDelegate.isServer(oaObj) || OAObjectReflectDelegate.isReferenceHubLoaded((OAObject)newObj, revLinkInfo.getName())) { hub = (Hub) OAObjectReflectDelegate.getProperty((OAObject)newObj, revLinkInfo.getName()); // 20130630 added autoAttach check boolean bAutoAdd = OAObjectDelegate.getAutoAdd(oaObj); if (bAutoAdd && hub != null) { hub.add(oaObj); if (oaObj.isNew()) { OAObject objMaster = hub.getMasterObject(); if (objMaster != null) { if (!OAObjectDelegate.getAutoAdd(objMaster)) { // turn off autoAdd for this object OAObjectDelegate.setAutoAdd(oaObj, false); } } } } } } catch (Exception e) { LOG.log(Level.WARNING, "exception while updating link", e); } } // reset Hub activeObjects in shared hubs if (alUpdateHub != null) { int x = alUpdateHub.size(); for (int i=0; i





© 2015 - 2025 Weber Informatics LLC | Privacy Policy