/** * Refresh locks held by the authorization <code>authID</code>. * * <p>(remember that the lock may have expired) * * @param authID Authorization identifing Lock to refresh * @param transaction Transaction with authorization for lockID * @return <code>true</code> if lock was found and refreshed * @throws IOException If transaction not authorized to refresh authID * @throws IllegalArgumentException If authID or transaction not provided */ public synchronized boolean refresh(String authID, Transaction transaction) throws IOException { if (authID == null) { throw new IllegalArgumentException("lockID required"); } if ((transaction == null) || (transaction == Transaction.AUTO_COMMIT)) { throw new IllegalArgumentException( "Tansaction required (with authorization for " + authID + ")"); } Lock lock; boolean refresh = false; for (Iterator i = allLocks().iterator(); i.hasNext(); ) { lock = (Lock) i.next(); if (lock.isExpired()) { i.remove(); } else if (lock.isMatch(authID)) { if (lock.isAuthorized(transaction)) { lock.refresh(); refresh = true; } else { throw new IOException("Not authorized to refresh " + lock); } } } return refresh; }
/** * Release locks held by the authorization <code>authID</code>. * * <p>(remember that the lock may have expired) * * @param authID Authorization identifing Lock to release * @param transaction Transaction with authorization for lockID * @return <code>true</code> if lock was found and released * @throws IOException If transaction not authorized to release authID * @throws IllegalArgumentException If authID or transaction not provided */ public boolean release(String authID, Transaction transaction) throws IOException { // LOGGER.info("release called on lock: " + authID + ", trans: " // + transaction); if (authID == null) { throw new IllegalArgumentException("lockID required"); } if ((transaction == null) || (transaction == Transaction.AUTO_COMMIT)) { throw new IllegalArgumentException( "Tansaction required (with authorization for " + authID + ")"); } Lock lock; boolean release = false; // This could be done more efficiently, and perhaps cleaner, // but these maps within a map are just nasty. The previous way of // calling iterator.remove() didn't actually remove anything, as it // was only iterating through the values of a map, which I believe // java just copies, so it's immutable. Or perhaps we just moved // through too many iterator layers... for (Iterator i = lockTables.values().iterator(); i.hasNext(); ) { Map fidMap = (Map) i.next(); Set unLockedFids = new HashSet(); for (Iterator j = fidMap.keySet().iterator(); j.hasNext(); ) { String fid = (String) j.next(); lock = (Lock) fidMap.get(fid); // LOGGER.info("checking lock " + lock + ", is match " // + lock.isMatch(authID)); if (lock.isExpired()) { unLockedFids.add(fid); // fidMap.remove(fid); concurrent modification error. } else if (lock.isMatch(authID)) { // LOGGER.info("matches, is authorized: " // + lock.isAuthorized(transaction)); if (lock.isAuthorized(transaction)) { unLockedFids.add(fid); // fidMap.remove(fid); release = true; } else { throw new IOException("Not authorized to release " + lock); } } } for (Iterator k = unLockedFids.iterator(); k.hasNext(); ) { fidMap.remove(k.next()); } } return release; }
/** * Checks mutability of featureID for this transaction. * * <p>Two behaviors are defined by FeatureLocking: * * <ul> * <li>TransactionLock (Blocking): lock held by a Transaction<br> * Authorization is granted to the Transaction holding the Lock. Conflict will result in a * block until the Transaction holding the lock completes. (This behavior is equivalent to a * Database row-lock, or a java synchronized statement) * <li>FeatureLock (Error): lock held by a FeatureLock<br> * Authorization is based on the set of Authorization IDs held by the provided Transaction. * Conflict will result in an error. (This behavior is equivalent to the WFS locking * specification) * </ul> * * <p>Right now we are just going to error out with an exception * * @param typeName Feature type to check against * @param featureID FeatureID to check * @param transaction Provides Authorization * @throws FeatureLockException If transaction does not have sufficient authroization */ public void assertAccess(String typeName, String featureID, Transaction transaction) throws FeatureLockException { Lock lock = getLock(typeName, featureID); // LOGGER.info("asserting access on lock for " + typeName + ", fid: " // + featureID + ", transaction: " + transaction + ", lock " + lock); if ((lock != null) && !lock.isAuthorized(transaction)) { throw new FeatureLockException( "Transaction does not have authorization for " + typeName + ":" + featureID); } }