List of usage examples for java.util.concurrent.locks ReadWriteLock writeLock
Lock writeLock();
From source file:net.siegmar.japtproxy.misc.IOHandler.java
/** * This method is responsible for fetching remote data (if needed) and * sending the data (locally stored, or remotely fetched) to the client. * * @param requestedData the requested data * @param poolObject the pool object * @param targetResource the remote resource link * @param res the HttpServletResponse object * @return true if the file was sent from cache, false otherwise * @throws IOException is thrown if a problem occured while sending data * @throws net.siegmar.japtproxy.exception.ResourceUnavailableException is thrown if the resource was not found *//*from www . j a v a 2 s. c o m*/ public boolean sendAndSave(final RequestedData requestedData, final PoolObject poolObject, final URL targetResource, final HttpServletResponse res) throws IOException, ResourceUnavailableException, InitializationException { final String lockIdentifier = requestedData.getRequestedResource(); final ReadWriteLock lock = ResourceLock.obtainLocker(lockIdentifier); final Lock readLock = lock.readLock(); LockStatus lockStatus; readLock.lock(); lockStatus = LockStatus.READ; LOG.debug("Obtained readLock for '{}'", lockIdentifier); final long poolModification = poolObject.getLastModified(); FetchedResource fetchedResource = null; OutputStream saveOs = null; InputStream is = null; try { if (poolModification != 0) { if (!isNewVersionCheckRequired(poolObject, requestedData.getRequestedResource())) { LOG.debug("Local object exists and no need to do a version check - sending local object"); sendLocalFile(poolObject, requestedData.getRequestModifiedSince(), res); return true; } LOG.debug("Local object exists but new version check is required"); } else { LOG.debug("No local object exists - requesting remote host"); } // Get a fetcher (http, ftp) for the current targetResource final Fetcher fetcher = fetcherPool.getInstance(targetResource); if (fetcher == null) { throw new InitializationException("No fetcher found for resource '" + targetResource + "'"); } fetchedResource = fetcher.fetch(targetResource, poolModification, requestedData.getUserAgent()); final String contentType = fetchedResource.getContentType(); final long remoteModification = fetchedResource.getLastModified(); final long contentLength = fetchedResource.getContentLength(); if (remoteModification != 0 && poolModification > remoteModification) { LOG.warn( "Remote object is older than local pool object " + "(Remote timestamp: {} - Local timestamp: {}). " + "Object won't get updated! Check this manually!", Util.getSimpleDateFromTimestamp(remoteModification), Util.getSimpleDateFromTimestamp(poolModification)); } setHeader(res, fetchedResource); if (!fetchedResource.isModified()) { LOG.debug("Remote resource has no new version - sending local object"); sendLocalFile(poolObject, requestedData.getRequestModifiedSince(), res); return true; } if (LOG.isDebugEnabled()) { if (poolModification != 0) { // Pool file exists, but it is out of date LOG.debug( "Newer version found (old Last-Modified: {}) - Request '{}', Last-Modified: {}, " + "Content-Type: {}, Content-Length: {}", Util.getSimpleDateFromTimestamp(poolModification), targetResource, Util.getSimpleDateFromTimestamp(remoteModification), contentType, contentLength); } else { // No pool file exists LOG.debug("Request '{}', Last-Modified: {}, Content-Type: {}, Content-Length: {}", targetResource, Util.getSimpleDateFromTimestamp(remoteModification), contentType, contentLength); } } readLock.unlock(); lock.writeLock().lock(); lockStatus = LockStatus.WRITE; LOG.debug("Obtained writeLock for '{}'", lockIdentifier); is = fetchedResource.getInputStream(); LOG.info("Sending remote object '{}'", poolObject.getName()); saveOs = new TeeOutputStream(poolObject.getOutputStream(), res.getOutputStream()); final long bytesCopied = IOUtils.copyLarge(is, saveOs); LOG.debug("Data sent to file and client"); poolObject.setLastModified(remoteModification); if (contentLength != -1 && bytesCopied != contentLength) { throw new IOException( String.format("Received file has invalid file size - " + "only %d of %d were downloaded", bytesCopied, contentLength)); } poolObject.store(); return false; } catch (final IOException e) { // Remove pool file if it was created by this thread if (poolModification == 0) { poolObject.remove(); } throw e; } finally { IOUtils.closeQuietly(is); IOUtils.closeQuietly(saveOs); if (fetchedResource != null) { fetchedResource.close(); } if (lockStatus == LockStatus.WRITE) { LOG.debug("Released writeLock for '{}'", lockIdentifier); lock.writeLock().unlock(); } else { LOG.debug("Released readLock for '{}'", lockIdentifier); readLock.unlock(); } ResourceLock.releaseLocker(lockIdentifier); } }