Changeset 5990


Ignore:
Timestamp:
Mar 5, 2012, 8:50:19 AM (11 years ago)
Author:
Nicklas Nordborg
Message:

Fixes #1667: Delete of items in trash is aborted if user logs off

The trashcan now uses a cloned session control and should not be affected if something happens (such as logout) with the original session control.

Location:
branches/3.0-stable/src/core/net/sf/basedb/core
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/3.0-stable/src/core/net/sf/basedb/core/SessionControl.java

    r5829 r5990  
    514514
    515515  /**
    516     Log in as another user. If this call is successful, you will get a new
    517     <code>SessionControl</code> object which is equivalent to a <code>SessionControl</code>
    518     where that user logged in by normal means. This method requires that the logged
    519     in user has {@link Permission#ACT_AS_ANOTHER_USER} permission.
     516    Log in as another user or create a clone of the currently logged in user's session.
     517    If this call is successful, you will get a new <code>SessionControl</code> object which
     518    is equivalent to a <code>SessionControl</code> where that user logged in by normal means.
     519    This method requires that the logged in user has {@link Permission#ACT_AS_ANOTHER_USER}
     520    permission or that the userId is the same as the currently logged in user.
    520521
    521522    @param userId The id of the user to login as
     
    524525    @throws ItemNotFoundException If no user with the specified id exists
    525526    @throws PermissionDeniedException If the logged in user doesn't
    526       have {@link Permission#ACT_AS_ANOTHER_USER} permission
     527      have {@link Permission#ACT_AS_ANOTHER_USER} permission and the userId
     528      is a different user from the currently logged in user
    527529    @throws BaseException If there is another error
    528530  */
     
    530532    throws ItemNotFoundException, PermissionDeniedException, BaseException
    531533  {
    532     if (!hasSystemPermission(Permission.ACT_AS_ANOTHER_USER))
     534    if (!hasSystemPermission(Permission.ACT_AS_ANOTHER_USER) && userId != getLoggedInUserId())
    533535    {
    534536      throw new PermissionDeniedException("No permission to act as another user.");
  • branches/3.0-stable/src/core/net/sf/basedb/core/Trashcan.java

    r4517 r5990  
    2323package net.sf.basedb.core;
    2424
     25import net.sf.basedb.core.Application.Pinger;
    2526import net.sf.basedb.core.data.BasicData;
    2627import net.sf.basedb.core.data.RemovableData;
     
    172173    and some may not.
    173174   
    174     @param sc The session control to use for connecting to the database
     175    @param sc The session control to use for connecting to the database. To
     176      avoid multithread-related problems the session control is cloned
     177      before being used by this method.
    175178    @param items The items to remove
    176179    @param ignoreFlag TRUE to also remove items that hasn't been flagged for removal
     
    211214
    212215    DbControl dc = null;
    213     // We try to delete items from the set as long as there are items
    214     // left and at least one item was deleted in the last iteration
    215     do
    216     {
    217       ThreadSignalHandler.checkInterrupted();
    218       dc = sc.newDbControl();
    219       log.debug("Start new delete transaction");
    220       try
    221       {
    222         removedInTransaction = 0;
    223         Iterator<Identifiable> iterator = itemsToRemove.iterator();
    224         deleteTransaction:
    225         while (iterator.hasNext())
     216    Pinger pinger = null;
     217    SessionControl sc2 = null;
     218    try
     219    {
     220      // We create an impersonated session control to
     221      // avoid issues where the original session control is closed,
     222      // for example, due to the user logging out
     223      sc2 = sc.impersonateLogin(sc.getLoggedInUserId(), "Deleting items from trashcan");
     224      pinger = Application.newPinger(sc2);
     225      // We try to delete items from the set as long as there are items
     226      // left and at least one item was deleted in the last iteration
     227      do
     228      {
     229        ThreadSignalHandler.checkInterrupted();
     230        dc = sc2.newDbControl();
     231        log.debug("Start new delete transaction");
     232        try
    226233        {
    227           ThreadSignalHandler.checkInterrupted();
    228           Identifiable item = iterator.next();
     234          removedInTransaction = 0;
     235          Iterator<Identifiable> iterator = itemsToRemove.iterator();
     236          deleteTransaction:
     237          while (iterator.hasNext())
     238          {
     239            ThreadSignalHandler.checkInterrupted();
     240            Identifiable item = iterator.next();
     241            if (progress != null)
     242            {
     243              String name = item instanceof Nameable ? ((Nameable)item).getName() : item.toString();
     244              progress.display((int)(numRemoved * progressFactor), "Remove " +
     245                  item.getType() + ": " + name +
     246                  " (" + (numRemoved + 1) + " of " + numToRemove + ")");
     247            }
     248            BasicItem basicItem = item.getType().getById(dc, item.getId());
     249            if (!basicItem.isUsed())
     250            {
     251              if (isDebug) log.debug("Deleting item " + basicItem);
     252              dc.deleteItem(basicItem);
     253              numRemoved++;
     254              removedInTransaction++;
     255              iterator.remove();
     256            }
     257            else
     258            {
     259              if (isDebug) log.debug("Item is used: " + basicItem);
     260              if (progress != null) progress.append(" [USED]");
     261              if (removedInTransaction > 0)
     262              {
     263                // Commit, start new transaction and try again
     264                break deleteTransaction;
     265              }
     266            }
     267          }
     268          log.debug("Committing transaction; " + removedInTransaction +
     269            " items scheduled for deletion; " + numRemoved + " total so far; " +
     270            itemsToRemove.size() + " remains in list");
    229271          if (progress != null)
    230272          {
    231             String name = item instanceof Nameable ? ((Nameable)item).getName() : item.toString();
    232             progress.display((int)(numRemoved * progressFactor), "Remove " +
    233                 item.getType() + ": " + name +
    234                 " (" + (numRemoved + 1) + " of " + numToRemove + ")");
     273            progress.display((int)(numRemoved * progressFactor),
     274              numRemoved + " of " + numToRemove + " items removed; flushing to database");
    235275          }
    236           BasicItem basicItem = item.getType().getById(dc, item.getId());
    237           if (!basicItem.isUsed())
    238           {
    239             if (isDebug) log.debug("Deleting item " + basicItem);
    240             dc.deleteItem(basicItem);
    241             numRemoved++;
    242             removedInTransaction++;
    243             iterator.remove();
    244           }
    245           else
    246           {
    247             if (isDebug) log.debug("Item is used: " + basicItem);
    248             if (progress != null) progress.append(" [USED]");
    249             if (removedInTransaction > 0)
    250             {
    251               // Commit, start new transaction and try again
    252               break deleteTransaction;
    253             }
    254           }
     276          dc.commit();
    255277        }
    256         log.debug("Committing transaction; " + removedInTransaction +
    257           " items scheduled for deletion; " + numRemoved + " total so far; " +
    258           itemsToRemove.size() + " remains in list");
    259         if (progress != null)
     278        finally
    260279        {
    261           progress.display((int)(numRemoved * progressFactor),
    262             numRemoved + " of " + numToRemove + " items removed; flushing to database");
     280          if (dc != null) dc.close();
    263281        }
    264         dc.commit();
    265       }
    266       finally
    267       {
    268         if (dc != null) dc.close();
    269       }
    270     } while (removedInTransaction > 0 && itemsToRemove.size() > 0);
     282      } while (removedInTransaction > 0 && itemsToRemove.size() > 0);
     283    }
     284    finally
     285    {
     286      if (pinger != null) pinger.stop();
     287      if (sc2 != null)
     288      {
     289        sc2.logout();
     290        sc2.close();
     291      }
     292    }
    271293   
    272294    if (progress != null)
Note: See TracChangeset for help on using the changeset viewer.