protected List<AbstractSession> filterByUserPrincipal( Collection<AbstractSession> values, Principal userPrincipal) throws IOException { List<AbstractSession> res = null; { if (values != null) { res = new ArrayList<AbstractSession>(); for (AbstractSession session : values) { expandSessionPrincipal(session); } if (userPrincipal == null) { for (AbstractSession session : values) { Principal p = session.getUserPrincipal(); if (p == null) { res.add(session); } } } else { for (AbstractSession session : values) { Principal p = session.getUserPrincipal(); if (PrincipalUtil.equalsIgnoreRealm(userPrincipal, p)) { res.add(session); } } } } } return res; }
/** * INTERNAL: Return the value of the field from the row or a value holder on the query to obtain * the object. Check for batch + aggregation reading. */ public Object valueFromRow( AbstractRecord row, JoinedAttributeManager joinManager, ObjectBuildingQuery query, AbstractSession executionSession) throws DatabaseException { Ref ref = (Ref) row.get(getField()); if (ref == null) { return null; } Struct struct; try { ((DatabaseAccessor) executionSession.getAccessor()).incrementCallCount(executionSession); java.sql.Connection connection = ((DatabaseAccessor) executionSession.getAccessor()).getConnection(); struct = (Struct) executionSession.getPlatform().getRefValue(ref, executionSession, connection); } catch (java.sql.SQLException exception) { throw DatabaseException.sqlException(exception, executionSession, false); } AbstractRecord targetRow = ((ObjectRelationalDataTypeDescriptor) getReferenceDescriptor()) .buildRowFromStructure(struct); ((DatabaseAccessor) executionSession.getAccessor()).decrementCallCount(); return getReferenceDescriptor().getObjectBuilder().buildObject(query, targetRow, joinManager); }
/** INTERNAL: Get a value from the object and set that in the respective field of the row. */ @Override public Object valueFromObject(Object object, DatabaseField field, AbstractSession session) { // First check if the value can be obtained from the value holder's row. AbstractRecord referenceRow = getIndirectionPolicy().extractReferenceRow(getAttributeValueFromObject(object)); if (referenceRow != null) { Object value = referenceRow.get(field); // Must ensure the classification to get a cache hit. try { value = session.getDatasourcePlatform().convertObject(value, getFieldClassification(field)); } catch (ConversionException e) { throw ConversionException.couldNotBeConverted(this, getDescriptor(), e); } return value; } // 2.5.1.6 PWK. added to support batch reading on variable one to ones Object referenceObject = getRealAttributeValueFromObject(object, session); String queryKeyName = (String) getSourceToTargetQueryKeyNames().get(field); ClassDescriptor objectDescriptor = session.getDescriptor(referenceObject.getClass()); DatabaseField targetField = objectDescriptor.getObjectBuilder().getTargetFieldForQueryKeyName(queryKeyName); if (targetField == null) { return null; } return objectDescriptor .getObjectBuilder() .extractValueFromObjectForField(referenceObject, targetField, session); }
/** * PUBLIC: Return a session broker that behaves as a client session broker. An acquire session * broker is done under the covers on each session inside the session broker, and a new broker is * returned. * * <p>NOTE: when finished with the client broker, it should be releases. See * releaseClientSessionBroker. */ public SessionBroker acquireClientSessionBroker() { log(SessionLog.FINER, SessionLog.CONNECTION, "acquire_client_session_broker"); SessionBroker clientBroker = copySessionBroker(); clientBroker.parent = this; clientBroker .getIdentityMapAccessorInstance() .setIdentityMapManager(getIdentityMapAccessorInstance().getIdentityMapManager()); clientBroker.commitManager = getCommitManager(); clientBroker.commandManager = getCommandManager(); clientBroker.externalTransactionController = getExternalTransactionController(); clientBroker.setServerPlatform(getServerPlatform()); String sessionName; AbstractSession serverSession; Iterator names = this.getSessionsByName().keySet().iterator(); while (names.hasNext()) { sessionName = (String) names.next(); serverSession = getSessionForName(sessionName); if (serverSession instanceof org.eclipse.persistence.sessions.server.ServerSession) { if (serverSession.getProject().hasIsolatedClasses()) { throw ValidationException.isolatedDataNotSupportedInSessionBroker(sessionName); } clientBroker.internalRegisterSession( sessionName, ((org.eclipse.persistence.sessions.server.ServerSession) serverSession) .acquireClientSession()); } else { throw ValidationException.cannotAcquireClientSessionFromSession(); } } clientBroker.initializeSequencing(); return clientBroker; }
/** Delete all of the objects with the matching class. */ public void deleteAllObjects(Class theClass, List objects, AbstractSession session) { ClassDescriptor descriptor = null; if (((UnitOfWorkImpl) session).shouldOrderUpdates()) { // bug 331064 - Sort the delete order objects = sort(theClass, objects); } int size = objects.size(); for (int index = 0; index < size; index++) { Object objectToDelete = objects.get(index); if (objectToDelete.getClass() == theClass) { if (descriptor == null) { descriptor = session.getDescriptor(theClass); } // PERF: Get the descriptor query, to avoid extra query creation. DeleteObjectQuery deleteQuery = descriptor.getQueryManager().getDeleteQuery(); if (deleteQuery == null) { deleteQuery = new DeleteObjectQuery(); deleteQuery.setDescriptor(descriptor); } else { // Ensure original query has been prepared. deleteQuery.checkPrepare(session, deleteQuery.getTranslationRow()); deleteQuery = (DeleteObjectQuery) deleteQuery.clone(); } deleteQuery.setIsExecutionClone(true); deleteQuery.setObject(objectToDelete); session.executeQuery(deleteQuery); } } }
/** * delete all of the objects as a single transaction. This should delete the object in the correct * order to maintain referential integrity. */ public void deleteAllObjects(List objects) throws RuntimeException, DatabaseException, OptimisticLockException { this.isActive = true; AbstractSession session = getSession(); session.beginTransaction(); try { // PERF: Optimize single object case. if (objects.size() == 1) { deleteAllObjects(objects.get(0).getClass(), objects, session); } else { List commitOrder = getCommitOrder(); for (int orderIndex = commitOrder.size() - 1; orderIndex >= 0; orderIndex--) { Class theClass = (Class) commitOrder.get(orderIndex); deleteAllObjects(theClass, objects, session); } } session.commitTransaction(); } catch (RuntimeException exception) { try { session.rollbackTransaction(); } catch (Exception ignore) { } throw exception; } finally { reinitialize(); this.isActive = false; } }
/** * INTERNAL: Return the results from exeucting the database query. the arguments should be a * database row with raw data values. Find the correct child session to broker the query to, and * return the result of the session executing the query. */ public Object internalExecuteQuery(DatabaseQuery query, AbstractRecord row) throws DatabaseException, QueryException { AbstractSession sessionByQuery = getSessionForQuery(query); // Note, this disables local profilers. return sessionByQuery.internalExecuteQuery(query, row); }
/** * Commit all of the objects of the class type in the change set. This allows for the order of the * classes to be processed optimally. */ protected void commitNewObjectsForClassWithChangeSet( UnitOfWorkChangeSet uowChangeSet, Class theClass) { Map<ObjectChangeSet, ObjectChangeSet> newObjectChangesList = uowChangeSet.getNewObjectChangeSets().get(theClass); if (newObjectChangesList != null) { // may be no changes for that class type. AbstractSession session = getSession(); ClassDescriptor descriptor = session.getDescriptor(theClass); List<ObjectChangeSet> newChangeSets = new ArrayList(newObjectChangesList.values()); int size = newChangeSets.size(); for (int index = 0; index < size; index++) { ObjectChangeSet changeSetToWrite = newChangeSets.get(index); Object objectToWrite = changeSetToWrite.getUnitOfWorkClone(); if (!isProcessedCommit(objectToWrite)) { // PERF: Get the descriptor query, to avoid extra query creation. InsertObjectQuery commitQuery = descriptor.getQueryManager().getInsertQuery(); if (commitQuery == null) { commitQuery = new InsertObjectQuery(); commitQuery.setDescriptor(descriptor); } else { // Ensure original query has been prepared. commitQuery.checkPrepare(session, commitQuery.getTranslationRow()); commitQuery = (InsertObjectQuery) commitQuery.clone(); } commitQuery.setIsExecutionClone(true); commitQuery.setObjectChangeSet(changeSetToWrite); commitQuery.setObject(objectToWrite); commitQuery.cascadeOnlyDependentParts(); commitQuery.setModifyRow(null); session.executeQuery(commitQuery); } uowChangeSet.putNewObjectInChangesList(changeSetToWrite, session); } } }
/** * PUBLIC: set the integrityChecker. IntegrityChecker holds all the ClassDescriptor Exceptions. */ public void setIntegrityChecker(IntegrityChecker integrityChecker) { super.setIntegrityChecker(integrityChecker); for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) { AbstractSession session = (AbstractSession) sessionEnum.next(); session.setIntegrityChecker(integrityChecker); } }
/** * PUBLIC: Set the message log. * * @see #logMessages() */ public void setLog(Writer log) { super.setLog(log); for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) { AbstractSession session = (AbstractSession) sessionEnum.next(); session.setLog(log); } }
/** * PUBLIC: Set the profiler for the session. This allows for performance operations to be * profiled. */ public void setProfiler(SessionProfiler profiler) { super.setProfiler(profiler); for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) { AbstractSession session = (AbstractSession) sessionEnum.next(); session.setProfiler(profiler); } }
/** PUBLIC: Return if this session is a server session broker. */ public boolean isServerSessionBroker() { for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) { AbstractSession session = (AbstractSession) sessionEnum.next(); if (session.isServerSession()) { return true; } } return false; }
/** * PUBLIC: Release the session. This does nothing by default, but allows for other sessions such * as the ClientSession to do something. */ public void release() { if (isClientSessionBroker()) { log(SessionLog.FINER, SessionLog.CONNECTION, "releasing_client_session_broker"); } AbstractSession session; for (Iterator enumtr = getSessionsByName().values().iterator(); enumtr.hasNext(); ) { session = (AbstractSession) enumtr.next(); session.release(); } super.release(); }
/** * INTERNAL: This method notifies the accessor that a particular sets of writes has completed. * This notification can be used for such thing as flushing the batch mechanism */ public void writesCompleted() { for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) { AbstractSession session = (AbstractSession) sessionEnum.next(); if (!session.isConnected()) { throw DatabaseException.databaseAccessorNotConnected(); } } for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) { AbstractSession session = (AbstractSession) sessionEnum.next(); session.writesCompleted(); } }
/** * INTERNAL: Commit the transaction on all child sessions. This assumes that the commit of the * transaction will not fail because all of the modification has already taken place and no errors * would have occurred. */ protected void basicCommitTransaction() throws DatabaseException { // Do one last check it make sure that all sessions are still connected. for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) { AbstractSession session = (AbstractSession) sessionEnum.next(); if (!session.isConnected()) { throw DatabaseException.databaseAccessorNotConnected(); } } for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) { AbstractSession session = (AbstractSession) sessionEnum.next(); session.commitTransaction(); } }
/** PUBLIC: Return if all sessions are still connected to the database. */ public boolean isConnected() { if ((getSessionsByName() == null) || (getSessionsByName().isEmpty())) { return false; } for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) { AbstractSession session = (AbstractSession) sessionEnum.next(); if (!session.isConnected()) { return false; } } return true; }
/** INTERNAL: Rollback the transaction on all child sessions. */ protected void basicRollbackTransaction() throws DatabaseException { DatabaseException globalException = null; for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) { AbstractSession session = (AbstractSession) sessionEnum.next(); try { session.rollbackTransaction(); } catch (DatabaseException exception) { globalException = exception; } } if (globalException != null) { throw globalException; } }
protected void expandSessionPrincipal(AbstractSession session) throws IOException { if (session != null) { String id = session.getId(); HttpSession httpSession = lookupHttpSessionById.get(id); // Set 'userPrincipal' upon session: { if (httpSession != null) { Principal userPrincipal = PrincipalSessionDecorator.getPrincipal(httpSession); if (userPrincipal != null) { session.setUserPrincipal(userPrincipal); } } } } }
/** * INTERNAL: Register the session under its name. All of the session's descriptors must have * already been registered. The session should not be connected and descriptors should not be * initialized. Used for client session broker */ public void internalRegisterSession(String name, AbstractSession session) { // Bug#3911318 Removed session brokers and sessions point to the same descriptors. // They don't need to be reassigned. Also the code to add read only classes has been removed // because client broker and server broker point to the same project. session.setIsInBroker(true); getSessionsByName().put(name, session); session.setBroker(this); session.setName(name); /* // The keys/classes must also be used as some descriptors may be under multiple classes. Iterator classes = session.getDescriptors().keySet().iterator(); while (classes.hasNext()) { Class descriptorClass = (Class)classes.next(); getSessionNamesByClass().put(descriptorClass, session); } */ }
/** * PUBLIC: Register the session under its name. All of the session's descriptors must have already * been registered. The session should not be connected and descriptors should not be initialized. */ public void registerSession(String name, AbstractSession session) { session.setIsInBroker(true); getSessionsByName().put(name, session); session.setBroker(this); session.setName(name); // The keys/classes must also be used as some descriptors may be under multiple classes. Iterator descriptors = session.getDescriptors().values().iterator(); Iterator classes = session.getDescriptors().keySet().iterator(); while (descriptors.hasNext()) { ClassDescriptor descriptor = (ClassDescriptor) descriptors.next(); Class descriptorClass = (Class) classes.next(); getSessionNamesByClass().put(descriptorClass, name); getDescriptors().put(descriptorClass, descriptor); } }
/** * INTERNAL: Compare the references of the two objects are the same, not the objects themselves. * Used for independent relationships. This is used for testing and validation purposes. * * <p>Must get separate fields for the objects because we may be adding a different class to the * attribute because of the interface */ @Override protected boolean compareObjectsWithoutPrivateOwned( Object firstObject, Object secondObject, AbstractSession session) { Object firstPrivateObject = getRealAttributeValueFromObject(firstObject, session); Object secondPrivateObject = getRealAttributeValueFromObject(secondObject, session); if ((firstPrivateObject == null) && (secondPrivateObject == null)) { return true; } if ((firstPrivateObject == null) || (secondPrivateObject == null)) { return false; } if (firstPrivateObject.getClass() != secondPrivateObject.getClass()) { return false; } Iterator targetKeys = getSourceToTargetQueryKeyNames().values().iterator(); ClassDescriptor descriptor = session.getDescriptor(firstPrivateObject.getClass()); ClassDescriptor descriptor2 = session.getDescriptor(secondPrivateObject.getClass()); while (targetKeys.hasNext()) { String queryKey = (String) targetKeys.next(); DatabaseField field = descriptor.getObjectBuilder().getFieldForQueryKeyName(queryKey); Object firstObjectField = descriptor .getObjectBuilder() .extractValueFromObjectForField(firstPrivateObject, field, session); DatabaseField field2 = descriptor2.getObjectBuilder().getFieldForQueryKeyName(queryKey); Object secondObjectField = descriptor2 .getObjectBuilder() .extractValueFromObjectForField(secondPrivateObject, field2, session); if (!((firstObjectField == null) && (secondObjectField == null))) { if ((firstObjectField == null) || (secondObjectField == null)) { return false; } if (!firstObjectField.equals(secondObjectField)) { return false; } } } return true; }
/** INTERNAL: Acquires a special historical session for reading objects as of a past time. */ public org.eclipse.persistence.sessions.Session acquireHistoricalSession(AsOfClause clause) throws ValidationException { if (isServerSessionBroker()) { throw ValidationException.cannotAcquireHistoricalSession(); } // ? logMessage("acquire_client_session_broker", (Object[])null); SessionBroker historicalBroker = copySessionBroker(); String sessionName; AbstractSession session; Iterator names = this.getSessionsByName().keySet().iterator(); while (names.hasNext()) { sessionName = (String) names.next(); session = getSessionForName(sessionName); historicalBroker.registerSession(sessionName, session.acquireHistoricalSession(clause)); } return historicalBroker; }
protected void expandSession(AbstractSession session) throws IOException { if (session != null) { String id = session.getId(); HttpSession httpSession = lookupHttpSessionById.get(id); // Set 'timeLastAccess' upon session: { if (httpSession != null) { Date timeLastAccess = new Date(httpSession.getLastAccessedTime()); session.setTimeLastAccess(timeLastAccess); } } expandSessionPrincipal(session); // Set 'requestURI' upon session: { if (httpSession != null) { List<String> requestURIs = RequestURISessionDecorator.getRequestURIs(httpSession); if (requestURIs != null) { Collections.reverse(requestURIs); // reverse the order! session.setRequestURIs(requestURIs); } } } // Set 'properties' upon session: { if (httpSession != null) { Map<String, Object> m = PropertiesSessionDecorator.getProperties(httpSession); if (m != null) { Properties properties = convertProperties(m); session.setProperties(properties); } } } } }
/** * Commit changed of the objects of the class type in the change set. This allows for the order of * the classes to be processed optimally. */ protected void commitChangedObjectsForClassWithChangeSet( UnitOfWorkChangeSet uowChangeSet, Class theClass) { Map<ObjectChangeSet, ObjectChangeSet> objectChangesList = uowChangeSet.getObjectChanges().get(theClass); if (objectChangesList != null) { // may be no changes for that class type. ClassDescriptor descriptor = null; AbstractSession session = getSession(); Collection<ObjectChangeSet> changes = objectChangesList.values(); if (((UnitOfWorkImpl) session).shouldOrderUpdates()) { changes = new ArrayList(objectChangesList.values()); Collections.sort((List) changes); } for (ObjectChangeSet changeSetToWrite : changes) { Object objectToWrite = changeSetToWrite.getUnitOfWorkClone(); if (descriptor == null) { descriptor = session.getDescriptor(objectToWrite); } if (!isProcessedCommit(objectToWrite)) { // Commit and resume on failure can cause a new change set to be in existing, so need to // check here. WriteObjectQuery commitQuery = null; if (changeSetToWrite.isNew()) { commitQuery = new InsertObjectQuery(); } else { commitQuery = new UpdateObjectQuery(); } commitQuery.setIsExecutionClone(true); commitQuery.setDescriptor(descriptor); commitQuery.setObjectChangeSet(changeSetToWrite); commitQuery.setObject(objectToWrite); commitQuery.cascadeOnlyDependentParts(); // removed checking session type to set cascade level // will always be a unitOfWork so we need to cascade dependent parts session.executeQuery(commitQuery); } } } }
/** INTERNAL: Return the implementor for a specified type */ protected Object getImplementorForType(Object type, AbstractSession session) { if (type == null) { return getTypeIndicatorTranslation().get(Helper.getNullWrapper()); } // Must ensure the type is the same, i.e. Integer != BigDecimal. try { type = session.getDatasourcePlatform().convertObject(type, getTypeField().getType()); } catch (ConversionException e) { throw ConversionException.couldNotBeConverted(this, getDescriptor(), e); } return getTypeIndicatorTranslation().get(type); }
// bug 331064 - Sort the delete order based on PKs. private List sort(Class theClass, List objects) { ClassDescriptor descriptor = session.getDescriptor(theClass); org.eclipse.persistence.internal.descriptors.ObjectBuilder objectBuilder = descriptor.getObjectBuilder(); int size = objects.size(); TreeMap sortedObjects = new TreeMap(); for (int index = 0; index < size; index++) { Object objectToDelete = objects.get(index); if (objectToDelete.getClass() == theClass) { sortedObjects.put( objectBuilder.extractPrimaryKeyFromObject(objectToDelete, session), objectToDelete); } } return new ArrayList(sortedObjects.values()); }
/** INTERNAL: Initialize the mapping. */ public void initialize(AbstractSession session) throws DescriptorException { setReferenceDescriptor(session.getDescriptor(getReferenceClass())); if (referenceDescriptor == null) { throw DescriptorException.descriptorIsMissing(getReferenceClass().getName(), this); } // For bug 2730536 convert the field to be an ObjectRelationalDatabaseField. ObjectRelationalDatabaseField field = (ObjectRelationalDatabaseField) getField(); field.setSqlType(java.sql.Types.REF); if (referenceDescriptor instanceof ObjectRelationalDataTypeDescriptor) { field.setSqlTypeName( ((ObjectRelationalDataTypeDescriptor) referenceDescriptor).getStructureName()); } setField(getDescriptor().buildField(getField())); setFields(collectFields()); // Ref mapping requires native connection in WLS as the Ref is wrapped. getDescriptor().setIsNativeConnectionRequired(true); }
/** * INTERNAL: Get a value from the object and set that in the respective field of the row. If the * mapping id target foreign key, you must only write the type into the roe, the rest will be * updated when the object itself is written */ @Override public void writeFromObjectIntoRowWithChangeRecord( ChangeRecord changeRecord, AbstractRecord record, AbstractSession session) { if (isReadOnly()) { return; } ObjectChangeSet changeSet = (ObjectChangeSet) ((ObjectReferenceChangeRecord) changeRecord).getNewValue(); if (changeSet == null) { writeFromNullObjectIntoRow(record); } else { Object referenceObject = changeSet.getUnitOfWorkClone(); if (isForeignKeyRelationship()) { Enumeration sourceFields = getForeignKeyFields().elements(); ClassDescriptor descriptor = session.getDescriptor(referenceObject.getClass()); while (sourceFields.hasMoreElements()) { DatabaseField sourceKey = (DatabaseField) sourceFields.nextElement(); String targetQueryKey = (String) getSourceToTargetQueryKeyNames().get(sourceKey); DatabaseField targetKeyField = descriptor.getObjectBuilder().getFieldForQueryKeyName(targetQueryKey); if (targetKeyField == null) { throw DescriptorException.variableOneToOneMappingIsNotDefinedProperly( this, descriptor, targetQueryKey); } Object referenceValue = descriptor .getObjectBuilder() .extractValueFromObjectForField(referenceObject, targetKeyField, session); record.put(sourceKey, referenceValue); } } if (getTypeField() != null) { record.put(getTypeField(), getTypeForImplementor(referenceObject.getClass())); } } }
/** INTERNAL: Begin the transaction on all child sessions. */ protected void basicBeginTransaction() throws DatabaseException { for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) { AbstractSession session = (AbstractSession) sessionEnum.next(); session.beginTransaction(); } }
/** * INTERNAL: Gets the session which this query will be executed on. Generally will be called * immediately before the call is translated, which is immediately before session.executeCall. * * <p>Since the execution session also knows the correct datasource platform to execute on, it is * often used in the mappings where the platform is needed for type conversion, or where calls are * translated. * * <p>Is also the session with the accessor. Will return a ClientSession if it is in transaction * and has a write connection. * * @return a session with a live accessor * @param query may store session name or reference class for brokers case */ public AbstractSession getExecutionSession(DatabaseQuery query) { AbstractSession sessionByQuery = getSessionForQuery(query); // Always forward to a registered session. return sessionByQuery.getExecutionSession(query); }