/** * Constructor, using the ObjectProvider of the "owner" and the field name. * * @param op The owner ObjectProvider * @param mmd Metadata for the member */ public ArrayList(ObjectProvider op, AbstractMemberMetaData mmd) { super(op, mmd); // Set up our delegate this.delegate = new java.util.ArrayList(); ExecutionContext ec = op.getExecutionContext(); allowNulls = SCOUtils.allowNullsInContainer(allowNulls, mmd); queued = ec.isDelayDatastoreOperationsEnabled(); useCache = SCOUtils.useContainerCache(op, mmd); if (!SCOUtils.collectionHasSerialisedElements(mmd) && mmd.getPersistenceModifier() == FieldPersistenceModifier.PERSISTENT) { ClassLoaderResolver clr = ec.getClassLoaderResolver(); this.backingStore = (ListStore) ((BackedSCOStoreManager) op.getStoreManager()) .getBackingStoreForField(clr, mmd, java.util.ArrayList.class); } if (NucleusLogger.PERSISTENCE.isDebugEnabled()) { NucleusLogger.PERSISTENCE.debug( SCOUtils.getContainerInfoMessage( op, ownerMmd.getName(), this, useCache, queued, allowNulls, SCOUtils.useCachedLazyLoading(op, ownerMmd))); } }
/** * Method to check if an element is already persistent, or is managed by a different * ExecutionContext. If not persistent, this will persist it. * * @param ec execution context * @param element The element * @param fieldValues any initial field values to use if persisting the element * @return Whether the element was persisted during this call */ protected boolean validateElementForWriting( ExecutionContext ec, Object element, FieldValues fieldValues) { // TODO Pass in cascade flag and if element not present then throw exception // Check the element type for this collection if (!elementIsPersistentInterface && !validateElementType(ec.getClassLoaderResolver(), element)) { throw new ClassCastException( Localiser.msg( "056033", element.getClass().getName(), ownerMemberMetaData.getFullFieldName(), elementType)); } boolean persisted = false; if (elementsAreEmbedded || elementsAreSerialised) { // Element is embedded/serialised so has no id } else { ObjectProvider elementSM = ec.findObjectProvider(element); if (elementSM != null && elementSM.isEmbedded()) { // Element is already with ObjectProvider and is embedded in another field! throw new NucleusUserException( Localiser.msg("056028", ownerMemberMetaData.getFullFieldName(), element)); } persisted = SCOUtils.validateObjectForWriting(ec, element, fieldValues); } return persisted; }
/** * Method to add a collection to the LinkedHashSet. * * @param elements The collection * @return Whether it was added ok. */ public boolean addAll(Collection elements) { boolean success = delegate.addAll(elements); if (ownerOP != null && ownerOP.getExecutionContext().getManageRelations()) { // Relationship management Iterator iter = elements.iterator(); while (iter.hasNext()) { ownerOP .getExecutionContext() .getRelationshipManager(ownerOP) .relationAdd(ownerMmd.getAbsoluteFieldNumber(), iter.next()); } } if (success) { if (SCOUtils.useQueuedUpdate(ownerOP)) { for (Object element : elements) { ownerOP .getExecutionContext() .addOperationToQueue( new CollectionAddOperation(ownerOP, ownerMmd.getAbsoluteFieldNumber(), element)); } } makeDirty(); if (ownerOP != null && !ownerOP.getExecutionContext().getTransaction().isActive()) { ownerOP.getExecutionContext().processNontransactionalUpdate(); } } return success; }
/** * Clear the association from owner to all elements. Provides cascade-delete when the elements * being deleted are PC types. * * @param ownerOP ObjectProvider for the container. */ public void clear(ObjectProvider ownerOP) { Collection dependentElements = null; CollectionMetaData collmd = ownerMemberMetaData.getCollection(); boolean dependent = collmd.isDependentElement(); if (ownerMemberMetaData.isCascadeRemoveOrphans()) { dependent = true; } if (dependent && !collmd.isEmbeddedElement() && !collmd.isSerializedElement()) { // Retain the dependent elements that need deleting after clearing dependentElements = new HashSet(); Iterator iter = iterator(ownerOP); while (iter.hasNext()) { dependentElements.add(iter.next()); } } executeClear(ownerOP); // Cascade-delete if (dependentElements != null && dependentElements.size() > 0) { Iterator iter = dependentElements.iterator(); while (iter.hasNext()) { Object obj = iter.next(); if (ownerOP.getExecutionContext().getApiAdapter().isDeleted(obj)) { // Element is tagged for deletion so will be deleted at flush(), and we dont need it // immediately } else { ownerOP.getExecutionContext().deleteObjectInternal(obj); } } } }
/** * Method to add the specified Map's values under their keys here. * * @param m The map */ public void putAll(java.util.Map m) { delegate.putAll(m); makeDirty(); if (ownerOP != null && !ownerOP.getExecutionContext().getTransaction().isActive()) { ownerOP.getExecutionContext().processNontransactionalUpdate(); } }
/** * Method to add a value against a key to the SortedMap. * * @param key The key * @param value The value * @return The previous value for the specified key. */ public Object put(Object key, Object value) { Object oldValue = delegate.put(key, value); makeDirty(); if (ownerOP != null && !ownerOP.getExecutionContext().getTransaction().isActive()) { ownerOP.getExecutionContext().processNontransactionalUpdate(); } return oldValue; }
/** * Method to poll the next element in the Queue. * * @return The element (now removed) */ public synchronized Object poll() { Object obj = delegate.poll(); makeDirty(); if (ownerOP != null && !ownerOP.getExecutionContext().getTransaction().isActive()) { ownerOP.getExecutionContext().processNontransactionalUpdate(); } return obj; }
/** Utility to mark the object as dirty */ public void makeDirty() { if (ownerOP != null) { ownerOP.makeDirty(ownerMmd.getAbsoluteFieldNumber()); if (!ownerOP.getExecutionContext().getTransaction().isActive()) { ownerOP.getExecutionContext().processNontransactionalUpdate(); } } }
/** * Clear the association from owner to all elements. Provides cascade-delete when the elements * being deleted are PC types. * * @param ownerOP ObjectProvider for the container. */ public void clear(ObjectProvider ownerOP) { Collection dependentElements = null; CollectionMetaData collmd = ownerMemberMetaData.getCollection(); boolean dependent = collmd.isDependentElement(); if (ownerMemberMetaData.isCascadeRemoveOrphans()) { dependent = true; } if (dependent && !collmd.isEmbeddedElement() && !collmd.isSerializedElement()) { // Retain the dependent elements that need deleting after clearing dependentElements = new HashSet(); Iterator iter = iterator(ownerOP); while (iter.hasNext()) { dependentElements.add(iter.next()); } } String clearStmt = getClearStmt(); try { ExecutionContext ec = ownerOP.getExecutionContext(); ManagedConnection mconn = storeMgr.getConnection(ec); SQLController sqlControl = storeMgr.getSQLController(); try { PreparedStatement ps = sqlControl.getStatementForUpdate(mconn, clearStmt, false); try { int jdbcPosition = 1; jdbcPosition = BackingStoreHelper.populateOwnerInStatement(ownerOP, ec, ps, jdbcPosition, this); if (relationDiscriminatorMapping != null) { BackingStoreHelper.populateRelationDiscriminatorInStatement(ec, ps, jdbcPosition, this); } sqlControl.executeStatementUpdate(ec, mconn, clearStmt, ps, true); } finally { sqlControl.closeStatement(mconn, ps); } } finally { mconn.release(); } } catch (SQLException e) { throw new NucleusDataStoreException(Localiser.msg("056013", clearStmt), e); } // Cascade-delete if (dependentElements != null && dependentElements.size() > 0) { Iterator iter = dependentElements.iterator(); while (iter.hasNext()) { Object obj = iter.next(); if (ownerOP.getExecutionContext().getApiAdapter().isDeleted(obj)) { // Element is tagged for deletion so will be deleted at flush(), and we dont need it // immediately } else { ownerOP.getExecutionContext().deleteObjectInternal(obj); } } } }
/** * Method to retain a Collection of elements (and remove all others). * * @param c The collection to retain * @return Whether they were retained successfully. */ public synchronized boolean retainAll(java.util.Collection c) { boolean success = delegate.retainAll(c); if (success) { makeDirty(); if (ownerOP != null && !ownerOP.getExecutionContext().getTransaction().isActive()) { ownerOP.getExecutionContext().processNontransactionalUpdate(); } } return success; }
public FieldManager getFieldManagerForResultProcessing( ObjectProvider op, Object resultSet, StatementClassMapping resultMappings) { ExecutionContext ec = op.getExecutionContext(); Class<?> cls = ec.getClassLoaderResolver().classForName(op.getClassMetaData().getFullClassName()); Object internalKey = EntityUtils.idToInternalKey(ec, cls, resultSet, true); // Need to provide this to the field manager in the form of the pk // of the type: Key, Long, encoded String, or unencoded String return new KeyOnlyFieldManager(internalKey); }
/** * Method to offer an element to the Queue. * * @param element The element to offer * @return Whether it was added successfully. */ public synchronized boolean offer(Object element) { boolean success = delegate.offer(element); if (success) { makeDirty(); if (ownerOP != null && !ownerOP.getExecutionContext().getTransaction().isActive()) { ownerOP.getExecutionContext().processNontransactionalUpdate(); } } return success; }
/** * Method to check if an element is already persistent or is persistent but managed by a different * ExecutionContext. * * @param op The ObjectProvider of this owner * @param element The element * @return Whether it is valid for reading. */ protected boolean validateElementForReading(ObjectProvider op, Object element) { if (!validateElementType(op.getExecutionContext().getClassLoaderResolver(), element)) { return false; } if (element != null && !elementsAreEmbedded && !elementsAreSerialised) { ExecutionContext ec = op.getExecutionContext(); if ((!ec.getApiAdapter().isPersistent(element) || ec != ec.getApiAdapter().getExecutionContext(element)) && !ec.getApiAdapter().isDetached(element)) { return false; } } return true; }
public void executeClear(ObjectProvider ownerOP) { String clearStmt = getClearStmt(); try { ExecutionContext ec = ownerOP.getExecutionContext(); ManagedConnection mconn = storeMgr.getConnection(ec); SQLController sqlControl = storeMgr.getSQLController(); try { PreparedStatement ps = sqlControl.getStatementForUpdate(mconn, clearStmt, false); try { int jdbcPosition = 1; jdbcPosition = BackingStoreHelper.populateOwnerInStatement(ownerOP, ec, ps, jdbcPosition, this); if (getRelationDiscriminatorMapping() != null) { BackingStoreHelper.populateRelationDiscriminatorInStatement(ec, ps, jdbcPosition, this); } sqlControl.executeStatementUpdate(ec, mconn, clearStmt, ps, true); } finally { sqlControl.closeStatement(mconn, ps); } } finally { mconn.release(); } } catch (SQLException e) { throw new NucleusDataStoreException(Localiser.msg("056013", clearStmt), e); } }
/** Method to clear the Collection. */ public synchronized void clear() { if (ownerOP != null && !delegate.isEmpty()) { // Cascade delete if (SCOUtils.hasDependentElement(ownerMmd)) { Iterator iter = delegate.iterator(); while (iter.hasNext()) { ownerOP.getExecutionContext().deleteObjectInternal(iter.next()); } } } delegate.clear(); makeDirty(); if (ownerOP != null && !ownerOP.getExecutionContext().getTransaction().isActive()) { ownerOP.getExecutionContext().processNontransactionalUpdate(); } }
/** Convenience method to set up the delegate respecting any comparator specified in MetaData. */ protected void initialiseDelegate() { Comparator comparator = SCOUtils.getComparator(ownerMmd, ownerOP.getExecutionContext().getClassLoaderResolver()); if (comparator != null) { this.delegate = new java.util.TreeMap(comparator); } else { this.delegate = new java.util.TreeMap(); } }
/** * Method to remove an element from the List * * @param element The Element to remove * @return Whether it was removed successfully. */ public synchronized boolean remove(Object element, boolean allowCascadeDelete) { boolean success = delegate.remove(element); if (ownerOP != null && allowCascadeDelete) { // Cascade delete if (SCOUtils.hasDependentElement(ownerMmd)) { ownerOP.getExecutionContext().deleteObjectInternal(element); } } if (success) { makeDirty(); if (ownerOP != null && !ownerOP.getExecutionContext().getTransaction().isActive()) { ownerOP.getExecutionContext().processNontransactionalUpdate(); } } return success; }
/** Method to initialise the SCO for use. */ public void initialise() { initialiseDelegate(); if (NucleusLogger.PERSISTENCE.isDebugEnabled()) { NucleusLogger.PERSISTENCE.debug( LOCALISER.msg( "023003", ownerOP.getObjectAsPrintable(), ownerMmd.getName(), "" + size(), SCOUtils.getSCOWrapperOptionsMessage(true, false, false, false))); } }
public int getSize(ObjectProvider ownerOP) { int numRows; String sizeStmt = getSizeStmt(); try { ExecutionContext ec = ownerOP.getExecutionContext(); ManagedConnection mconn = storeMgr.getConnection(ec); SQLController sqlControl = storeMgr.getSQLController(); try { PreparedStatement ps = sqlControl.getStatementForQuery(mconn, sizeStmt); try { int jdbcPosition = 1; jdbcPosition = BackingStoreHelper.populateOwnerInStatement(ownerOP, ec, ps, jdbcPosition, this); if (getElementInfo() != null && getElementInfo().length == 1) { // TODO Allow for multiple element types (e.g interface implementations) for (int i = 0; i < getElementInfo().length; i++) { if (getElementInfo()[i].getDiscriminatorMapping() != null) { jdbcPosition = BackingStoreHelper.populateElementDiscriminatorInStatement( ec, ps, jdbcPosition, true, getElementInfo()[i], clr); } } } if (getRelationDiscriminatorMapping() != null) { jdbcPosition = BackingStoreHelper.populateRelationDiscriminatorInStatement( ec, ps, jdbcPosition, this); } ResultSet rs = sqlControl.executeStatementQuery(ec, mconn, sizeStmt, ps); try { if (!rs.next()) { throw new NucleusDataStoreException(Localiser.msg("056007", sizeStmt)); } numRows = rs.getInt(1); JDBCUtils.logWarnings(rs); } finally { rs.close(); } } finally { sqlControl.closeStatement(mconn, ps); } } finally { mconn.release(); } } catch (SQLException e) { throw new NucleusDataStoreException(Localiser.msg("056007", sizeStmt), e); } return numRows; }
/* (non-Javadoc) * @see org.datanucleus.store.fieldmanager.AbstractFieldManager#fetchObjectField(int) */ @Override public Object fetchObjectField(int fieldNumber) { ClassLoaderResolver clr = ec.getClassLoaderResolver(); AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber); RelationType relationType = mmd.getRelationType(clr); EmbeddedMetaData embmd = mmds.get(0).getEmbeddedMetaData(); if (mmds.size() == 1 && embmd != null && embmd.getOwnerMember() != null && embmd.getOwnerMember().equals(mmd.getName())) { // Special case of this being a link back to the owner. TODO Repeat this for nested and their // owners ObjectProvider[] ownerOps = ec.getOwnersForEmbeddedObjectProvider(op); return (ownerOps != null && ownerOps.length > 0 ? ownerOps[0].getObject() : null); } if (relationType != RelationType.NONE && MetaDataUtils.getInstance() .isMemberEmbedded(ec.getMetaDataManager(), clr, mmd, relationType, null)) { // Embedded field if (RelationType.isRelationSingleValued(relationType)) { // TODO Cater for null value detection List<AbstractMemberMetaData> embMmds = new ArrayList<AbstractMemberMetaData>(mmds); embMmds.add(mmd); AbstractClassMetaData embCmd = ec.getMetaDataManager().getMetaDataForClass(mmd.getType(), clr); ObjectProvider embOP = ec.getNucleusContext() .getObjectProviderFactory() .newForEmbedded(ec, embCmd, op, fieldNumber); FieldManager ffm = new FetchEmbeddedFieldManager(embOP, result, embMmds, table); embOP.replaceFields(embCmd.getAllMemberPositions(), ffm); return embOP.getObject(); } } return fetchNonEmbeddedObjectField(mmd, relationType, clr); }
/** * Method to remove an element from the List * * @param element The Element to remove * @return Whether it was removed successfully. */ public boolean remove(Object element, boolean allowCascadeDelete) { boolean success = delegate.remove(element); if (ownerOP != null && ownerOP.getExecutionContext().getManageRelations()) { ownerOP .getExecutionContext() .getRelationshipManager(ownerOP) .relationRemove(ownerMmd.getAbsoluteFieldNumber(), element); } if (ownerOP != null && allowCascadeDelete) { // Cascade delete if (SCOUtils.useQueuedUpdate(ownerOP)) { // Queue the cascade delete ownerOP .getExecutionContext() .addOperationToQueue( new CollectionRemoveOperation( ownerOP, ownerMmd.getAbsoluteFieldNumber(), element, allowCascadeDelete)); } else if (SCOUtils.hasDependentElement(ownerMmd)) { // Perform the cascade delete ownerOP.getExecutionContext().deleteObjectInternal(element); } } if (success) { makeDirty(); if (ownerOP != null && !ownerOP.getExecutionContext().getTransaction().isActive()) { ownerOP.getExecutionContext().processNontransactionalUpdate(); } } return success; }
/** * Method to remove the value for a key from the SortedMap. * * @param key The key to remove * @return The value that was removed from this key. */ public Object remove(Object key) { Object value = delegate.remove(key); if (ownerOP != null) { // Cascade delete if (SCOUtils.hasDependentKey(ownerMmd) || SCOUtils.hasDependentValue(ownerMmd)) { if (SCOUtils.hasDependentKey(ownerMmd)) { ownerOP.getExecutionContext().deleteObjectInternal(key); } if (SCOUtils.hasDependentValue(ownerMmd)) { ownerOP.getExecutionContext().deleteObjectInternal(value); } } } makeDirty(); if (ownerOP != null && !ownerOP.getExecutionContext().getTransaction().isActive()) { ownerOP.getExecutionContext().processNontransactionalUpdate(); } return value; }
/** * Method to remove a Collection of elements. * * @param elements The collection to remove * @return Whether they were removed successfully. */ public synchronized boolean removeAll(java.util.Collection elements) { boolean success = delegate.removeAll(elements); if (ownerOP != null && elements != null && !elements.isEmpty()) { // Cascade delete if (SCOUtils.hasDependentElement(ownerMmd)) { Iterator iter = elements.iterator(); while (iter.hasNext()) { ownerOP.getExecutionContext().deleteObjectInternal(iter.next()); } } } if (success) { makeDirty(); if (ownerOP != null && !ownerOP.getExecutionContext().getTransaction().isActive()) { ownerOP.getExecutionContext().processNontransactionalUpdate(); } } return success; }
/** * Method to retain a Collection of elements (and remove all others). * * @param c The collection to retain * @return Whether they were retained successfully. */ public boolean retainAll(java.util.Collection c) { if (c == null) { throw new NullPointerException("Input collection was null"); } Collection collToRemove = new java.util.LinkedHashSet(); for (Object o : delegate) { if (!c.contains(o)) { collToRemove.add(o); } } boolean success = delegate.retainAll(c); if (success) { makeDirty(); if (SCOUtils.useQueuedUpdate(ownerOP)) { // Queue any cascade delete Iterator iter = collToRemove.iterator(); while (iter.hasNext()) { ownerOP .getExecutionContext() .addOperationToQueue( new CollectionRemoveOperation( ownerOP, ownerMmd.getAbsoluteFieldNumber(), iter.next(), true)); } } else if (SCOUtils.hasDependentElement(ownerMmd)) { // Perform the cascade delete Iterator iter = collToRemove.iterator(); while (iter.hasNext()) { ownerOP.getExecutionContext().deleteObjectInternal(iter.next()); } } if (ownerOP != null && !ownerOP.getExecutionContext().getTransaction().isActive()) { ownerOP.getExecutionContext().processNontransactionalUpdate(); } } return success; }
/** Method to clear the SortedMap. */ public void clear() { if (ownerOP != null && !delegate.isEmpty()) { // Cascade delete if (SCOUtils.hasDependentKey(ownerMmd) || SCOUtils.hasDependentValue(ownerMmd)) { Iterator<Map.Entry> entryIter = delegate.entrySet().iterator(); while (entryIter.hasNext()) { Map.Entry entry = entryIter.next(); if (SCOUtils.hasDependentKey(ownerMmd)) { ownerOP.getExecutionContext().deleteObjectInternal(entry.getKey()); } if (SCOUtils.hasDependentValue(ownerMmd)) { ownerOP.getExecutionContext().deleteObjectInternal(entry.getValue()); } } } } delegate.clear(); makeDirty(); if (ownerOP != null && !ownerOP.getExecutionContext().getTransaction().isActive()) { ownerOP.getExecutionContext().processNontransactionalUpdate(); } }
/** * Method to add an element to the LinkedHashSet. * * @param element The new element * @return Whether it was added ok. */ public boolean add(E element) { boolean success = delegate.add(element); if (ownerOP != null && ownerOP.getExecutionContext().getManageRelations()) { // Relationship management ownerOP .getExecutionContext() .getRelationshipManager(ownerOP) .relationAdd(ownerMmd.getAbsoluteFieldNumber(), element); } if (success) { if (SCOUtils.useQueuedUpdate(ownerOP)) { ownerOP .getExecutionContext() .addOperationToQueue( new CollectionAddOperation(ownerOP, ownerMmd.getAbsoluteFieldNumber(), element)); } makeDirty(); if (ownerOP != null && !ownerOP.getExecutionContext().getTransaction().isActive()) { ownerOP.getExecutionContext().processNontransactionalUpdate(); } } return success; }
/** * Method to return an attached copy of the passed (detached) value. The returned attached copy is * a SCO wrapper. Goes through the existing keys/values in the store for this owner field and * removes ones no longer present, and adds new keys/values. All keys/values in the (detached) * value are attached. * * @param value The new (map) value */ public void attachCopy(Object value) { java.util.Map m = (java.util.Map) value; // Attach all of the keys/values in the new map boolean keysWithoutIdentity = SCOUtils.mapHasKeysWithoutIdentity(ownerMmd); boolean valuesWithoutIdentity = SCOUtils.mapHasValuesWithoutIdentity(ownerMmd); java.util.Map attachedKeysValues = new java.util.TreeMap(); SCOUtils.attachCopyForMap( ownerOP, m.entrySet(), attachedKeysValues, keysWithoutIdentity, valuesWithoutIdentity); // Update the attached map with the detached elements SCOUtils.updateMapWithMapKeysValues( ownerOP.getExecutionContext().getApiAdapter(), this, attachedKeysValues); }
/** * Method to initialise the SCO from an existing value. * * @param c The object to set from * @param forInsert Whether the object needs inserting in the datastore with this value * @param forUpdate Whether to update the datastore with this value */ public void initialise(java.util.PriorityQueue c, boolean forInsert, boolean forUpdate) { if (c != null) { initialiseDelegate(); delegate.addAll(c); } else { initialiseDelegate(); } if (NucleusLogger.PERSISTENCE.isDebugEnabled()) { NucleusLogger.PERSISTENCE.debug( Localiser.msg( "023003", ownerOP.getObjectAsPrintable(), ownerMmd.getName(), "" + size(), SCOUtils.getSCOWrapperOptionsMessage(true, false, false, false))); } }
public void initialise(java.util.LinkedHashSet c) { if (c != null) { delegate = c; } else { delegate = new java.util.LinkedHashSet(); } if (NucleusLogger.PERSISTENCE.isDebugEnabled()) { NucleusLogger.PERSISTENCE.debug( Localiser.msg( "023003", this.getClass().getName(), ownerOP.getObjectAsPrintable(), ownerMmd.getName(), "" + size(), SCOUtils.getSCOWrapperOptionsMessage(true, false, true, false))); } }
/** * Method to initialise the SCO from an existing value. * * @param o Object to set value using. * @param forInsert Whether the object needs inserting in the datastore with this value * @param forUpdate Whether to update the datastore with this value */ public void initialise(Object o, boolean forInsert, boolean forUpdate) { java.util.Map m = (java.util.Map) o; if (m != null) { delegate = (java.util.HashMap) m; } else { delegate = new java.util.HashMap(); } if (NucleusLogger.PERSISTENCE.isDebugEnabled()) { NucleusLogger.PERSISTENCE.debug( LOCALISER.msg( "023003", ownerOP.getObjectAsPrintable(), ownerMmd.getName(), "" + size(), SCOUtils.getSCOWrapperOptionsMessage(true, false, true, false))); } }