List of usage examples for java.util.concurrent.locks Lock unlock
void unlock();
From source file:org.onosproject.drivers.bmv2.Bmv2FlowRuleProgrammable.java
@Override public Collection<FlowEntry> getFlowEntries() { if (!init()) { return Collections.emptyList(); }//ww w .j a va 2s . com DeviceId deviceId = handler().data().deviceId(); Bmv2DeviceAgent deviceAgent; try { deviceAgent = controller.getAgent(deviceId); } catch (Bmv2RuntimeException e) { log.error("Failed to get BMv2 device agent: {}", e.explain()); return Collections.emptyList(); } Bmv2DeviceContext context = contextService.getContext(deviceId); if (context == null) { log.warn("Unable to get device context for {}", deviceId); } Bmv2Interpreter interpreter = context.interpreter(); Bmv2Configuration configuration = context.configuration(); List<FlowEntry> entryList = Lists.newArrayList(); for (Bmv2TableModel table : configuration.tables()) { // For each table in the configuration AND exposed by the interpreter. if (!interpreter.tableIdMap().inverse().containsKey(table.name())) { continue; // next table } List<Bmv2ParsedTableEntry> installedEntries; try { installedEntries = deviceAgent.getTableEntries(table.name()); } catch (Bmv2RuntimeException e) { log.warn("Failed to get table entries of table {} of {}: {}", table.name(), deviceId, e.explain()); continue; // next table } for (Bmv2ParsedTableEntry parsedEntry : installedEntries) { Bmv2TableEntryReference entryRef = new Bmv2TableEntryReference(deviceId, table.name(), parsedEntry.matchKey()); Lock lock = ENTRY_LOCKS.computeIfAbsent(entryRef, key -> new ReentrantLock()); lock.lock(); try { Bmv2FlowRuleWrapper frWrapper = tableEntryService.lookup(entryRef); if (frWrapper == null) { log.debug( "Missing reference from table entry service. Deleting it. BUG? " + "deviceId={}, tableName={}, matchKey={}", deviceId, table.name(), entryRef.matchKey()); try { doRemove(deviceAgent, table.name(), parsedEntry.entryId(), parsedEntry.matchKey()); } catch (Bmv2RuntimeException e) { log.warn("Unable to remove inconsistent flow rule: {}", e.explain()); } continue; // next entry } long remoteEntryId = parsedEntry.entryId(); long localEntryId = frWrapper.entryId(); if (remoteEntryId != localEntryId) { log.debug( "getFlowEntries(): inconsistent entry id! BUG? Updating it... remote={}, local={}", remoteEntryId, localEntryId); frWrapper = new Bmv2FlowRuleWrapper(frWrapper.rule(), remoteEntryId, frWrapper.installedOnMillis()); tableEntryService.bind(entryRef, frWrapper); } long bytes = 0L; long packets = 0L; if (table.hasCounters()) { // Read counter values from device. try { Pair<Long, Long> counterValue = deviceAgent.readTableEntryCounter(table.name(), remoteEntryId); bytes = counterValue.getLeft(); packets = counterValue.getRight(); } catch (Bmv2RuntimeException e) { log.warn("Unable to get counters for entry {}/{} of device {}: {}", table.name(), remoteEntryId, deviceId, e.explain()); } } FlowEntry entry = new DefaultFlowEntry(frWrapper.rule(), ADDED, frWrapper.lifeInSeconds(), packets, bytes); entryList.add(entry); } finally { lock.unlock(); } } } return Collections.unmodifiableCollection(entryList); }
From source file:com.microsoft.tooling.msservices.helpers.azure.AzureManagerImpl.java
@NotNull private ReentrantReadWriteLock getUserLock(@NotNull UserInfo userInfo, boolean createOnMissing) throws AzureCmdException { Lock lock = createOnMissing ? userMapLock.writeLock() : userMapLock.readLock(); lock.lock();/*from w ww . j ava2 s .co m*/ try { if (!lockByUser.containsKey(userInfo)) { if (createOnMissing) { lockByUser.put(userInfo, new ReentrantReadWriteLock(false)); } else { throw new AzureCmdException("No access token for the specified User Information"); } } return lockByUser.get(userInfo); } finally { lock.unlock(); } }
From source file:com.funambol.pushlistener.service.taskexecutor.ScheduledTaskExecutor.java
/** * Cancels execution of the task identified by the given id and removes its * scheduled execution/*from w w w . java 2 s.c o m*/ * @param taskId the id of task to stop/remove * @param mayInterruptIfRunning true if the thread executing this task should * be interrupted; otherwise, in-progress tasks are allowed to complete * @return true if the task has been removed successfully, false otherwise (for instance * if the task doesn't exist) */ public boolean removeScheduledTask(long taskId, boolean mayInterruptIfRunning) { ScheduledTaskWrapper dummyTask = new ScheduledTaskWrapper(taskId); if (log.isTraceEnabled()) { log.trace("Removing task '" + taskId + "'"); } // // Locking the lock for this task so no other thread can handle it avoiding // conflict (what happens if a thread is removing it an another threead is // updating it ?) // Lock handlingTaskLock = getHandlingTaskLock(taskId); handlingTaskLock.lock(); try { ScheduledFuture scheduledFuture = null; ScheduledTaskWrapper scheduledTask = null; synchronized (scheduledFutures) { scheduledFuture = (ScheduledFuture) scheduledFutures.get(dummyTask); scheduledTask = (ScheduledTaskWrapper) scheduledFutures.getKey(scheduledFuture); } if (scheduledFuture != null) { scheduledFuture.cancel(mayInterruptIfRunning); if (scheduledTask != null) { try { scheduledTask.shutdown(); } catch (TaskException ex) { log.error("Error shutting down scheduled task '" + scheduledTask + "'", ex); } scheduledTask.setState(ScheduledTaskWrapper.State.SHUTDOWN); } synchronized (scheduledFutures) { // // Any time we remove the scheduledTask from scheduledFutures, // we try to remove the scheduledFuture from the queue. This // is not really needed because after a while this is performed // automatically but in this way we keep scheduledFutures and // the queue in sync // if (scheduledFuture instanceof Runnable) { super.remove((Runnable) scheduledFuture); } scheduledFutures.remove(scheduledTask); } if (log.isTraceEnabled()) { log.trace("Task '" + taskId + "' cancelled successfully"); } return true; } else { if (log.isTraceEnabled()) { log.trace("Task '" + taskId + "' seems not scheduled"); } return false; } } finally { handlingTaskLock.unlock(); } }
From source file:com.microsoft.tooling.msservices.helpers.azure.AzureManagerImpl.java
@NotNull private ReentrantReadWriteLock getSubscriptionLock(@NotNull String subscriptionId, boolean createOnMissing) throws AzureCmdException { Lock lock = createOnMissing ? subscriptionMapLock.writeLock() : subscriptionMapLock.readLock(); lock.lock();/*from w w w. ja v a2 s . co m*/ try { if (!lockBySubscriptionId.containsKey(subscriptionId)) { if (createOnMissing) { lockBySubscriptionId.put(subscriptionId, new ReentrantReadWriteLock(false)); } else { throw new AzureCmdException("No authentication information for the specified Subscription Id"); } } return lockBySubscriptionId.get(subscriptionId); } finally { lock.unlock(); } }
From source file:jp.aegif.nemaki.cmis.service.impl.ObjectServiceImpl.java
@Override public void setContentStream(CallContext callContext, String repositoryId, Holder<String> objectId, boolean overwriteFlag, ContentStream contentStream, Holder<String> changeToken) { exceptionService.invalidArgumentRequiredHolderString("objectId", objectId); Lock lock = threadLockService.getWriteLock(repositoryId, objectId.getValue()); try {//from ww w. ja v a 2s . c o m lock.lock(); // ////////////////// // General Exception // ////////////////// exceptionService.invalidArgumentRequired("contentStream", contentStream); Document doc = (Document) contentService.getContent(repositoryId, objectId.getValue()); exceptionService.objectNotFound(DomainType.OBJECT, doc, objectId.getValue()); exceptionService.permissionDenied(callContext, repositoryId, PermissionMapping.CAN_SET_CONTENT_DOCUMENT, doc); DocumentTypeDefinition td = (DocumentTypeDefinition) typeManager.getTypeDefinition(repositoryId, doc.getObjectType()); exceptionService.constraintImmutable(repositoryId, doc, td); // ////////////////// // Specific Exception // ////////////////// exceptionService.contentAlreadyExists(doc, overwriteFlag); exceptionService.streamNotSupported(td, contentStream); exceptionService.updateConflict(doc, changeToken); exceptionService.versioning(doc); Folder parent = contentService.getParent(repositoryId, objectId.getValue()); exceptionService.objectNotFoundParentFolder(repositoryId, objectId.getValue(), parent); // ////////////////// // Body of the method // ////////////////// String oldId = objectId.getValue(); // TODO Externalize versioningState if (doc.isPrivateWorkingCopy()) { Document result = contentService.replacePwc(callContext, repositoryId, doc, contentStream); objectId.setValue(result.getId()); } else { Document result = contentService.createDocumentWithNewStream(callContext, repositoryId, doc, contentStream); objectId.setValue(result.getId()); } nemakiCachePool.get(repositoryId).removeCmisCache(oldId); } finally { lock.unlock(); } }
From source file:org.geotools.gce.imagemosaic.catalog.GTDataStoreGranuleCatalog.java
@Override public void getGranuleDescriptors(Query query, final GranuleCatalogVisitor visitor) throws IOException { Utilities.ensureNonNull("query", query); final Query q = mergeHints(query); String typeName = q.getTypeName(); final Lock lock = rwLock.readLock(); try {/* w w w . j av a 2 s . c o m*/ lock.lock(); checkStore(); // // Load tiles informations, especially the bounds, which will be // reused // final SimpleFeatureSource featureSource = tileIndexStore.getFeatureSource(typeName); if (featureSource == null) { throw new NullPointerException( "The provided SimpleFeatureSource is null, it's impossible to create an index!"); } final SimpleFeatureCollection features = featureSource.getFeatures(q); if (features == null) throw new NullPointerException( "The provided SimpleFeatureCollection is null, it's impossible to create an index!"); if (LOGGER.isLoggable(Level.FINE)) LOGGER.fine("Index Loaded"); // visiting the features from the underlying store final DefaultProgressListener listener = new DefaultProgressListener(); features.accepts(new AbstractFeatureVisitor() { public void visit(Feature feature) { if (feature instanceof SimpleFeature) { // get the feature final SimpleFeature sf = (SimpleFeature) feature; MultiLevelROI footprint = getGranuleFootprint(sf); if (footprint == null || !footprint.isEmpty()) { final GranuleDescriptor granule = new GranuleDescriptor(sf, suggestedRasterSPI, pathType, locationAttribute, parentLocation, footprint, heterogeneous, q.getHints()); visitor.visit(granule, null); } // check if something bad occurred if (listener.isCanceled() || listener.hasExceptions()) { if (listener.hasExceptions()) { throw new RuntimeException(listener.getExceptions().peek()); } else { throw new IllegalStateException( "Feature visitor for query " + q + " has been canceled"); } } } } }, listener); } catch (Throwable e) { final IOException ioe = new IOException(); ioe.initCause(e); throw ioe; } finally { lock.unlock(); } }
From source file:org.apache.hadoop.hbase.master.AssignmentManager.java
/** * Bulk assign regions to <code>destination</code>. * @param destination/*from w w w . jav a 2s.c o m*/ * @param regions Regions to assign. * @return true if successful */ boolean assign(final ServerName destination, final List<HRegionInfo> regions) throws InterruptedException { long startTime = EnvironmentEdgeManager.currentTimeMillis(); try { int regionCount = regions.size(); if (regionCount == 0) { return true; } LOG.info("Assigning " + regionCount + " region(s) to " + destination.toString()); Set<String> encodedNames = new HashSet<String>(regionCount); for (HRegionInfo region : regions) { encodedNames.add(region.getEncodedName()); } List<HRegionInfo> failedToOpenRegions = new ArrayList<HRegionInfo>(); Map<String, Lock> locks = locker.acquireLocks(encodedNames); try { AtomicInteger counter = new AtomicInteger(0); Map<String, Integer> offlineNodesVersions = new ConcurrentHashMap<String, Integer>(); OfflineCallback cb = new OfflineCallback(watcher, destination, counter, offlineNodesVersions); Map<String, RegionPlan> plans = new HashMap<String, RegionPlan>(regions.size()); List<RegionState> states = new ArrayList<RegionState>(regions.size()); for (HRegionInfo region : regions) { String encodedName = region.getEncodedName(); if (!isDisabledorDisablingRegionInRIT(region)) { RegionState state = forceRegionStateToOffline(region, false); boolean onDeadServer = false; if (state != null) { if (regionStates.wasRegionOnDeadServer(encodedName)) { LOG.info("Skip assigning " + region.getRegionNameAsString() + ", it's host " + regionStates.getLastRegionServerOfRegion(encodedName) + " is dead but not processed yet"); onDeadServer = true; } else if (asyncSetOfflineInZooKeeper(state, cb, destination)) { RegionPlan plan = new RegionPlan(region, state.getServerName(), destination); plans.put(encodedName, plan); states.add(state); continue; } } // Reassign if the region wasn't on a dead server if (!onDeadServer) { LOG.info("failed to force region state to offline or " + "failed to set it offline in ZK, will reassign later: " + region); failedToOpenRegions.add(region); // assign individually later } } // Release the lock, this region is excluded from bulk assign because // we can't update its state, or set its znode to offline. Lock lock = locks.remove(encodedName); lock.unlock(); } // Wait until all unassigned nodes have been put up and watchers set. int total = states.size(); for (int oldCounter = 0; !server.isStopped();) { int count = counter.get(); if (oldCounter != count) { LOG.debug(destination.toString() + " unassigned znodes=" + count + " of total=" + total + "; oldCounter=" + oldCounter); oldCounter = count; } if (count >= total) break; Thread.sleep(5); } if (server.isStopped()) { return false; } // Add region plans, so we can updateTimers when one region is opened so // that unnecessary timeout on RIT is reduced. this.addPlans(plans); List<Triple<HRegionInfo, Integer, List<ServerName>>> regionOpenInfos = new ArrayList<Triple<HRegionInfo, Integer, List<ServerName>>>( states.size()); for (RegionState state : states) { HRegionInfo region = state.getRegion(); String encodedRegionName = region.getEncodedName(); Integer nodeVersion = offlineNodesVersions.get(encodedRegionName); if (nodeVersion == null || nodeVersion == -1) { LOG.warn("failed to offline in zookeeper: " + region); failedToOpenRegions.add(region); // assign individually later Lock lock = locks.remove(encodedRegionName); lock.unlock(); } else { regionStates.updateRegionState(region, State.PENDING_OPEN, destination); List<ServerName> favoredNodes = ServerName.EMPTY_SERVER_LIST; if (this.shouldAssignRegionsWithFavoredNodes) { favoredNodes = ((FavoredNodeLoadBalancer) this.balancer).getFavoredNodes(region); } regionOpenInfos.add(new Triple<HRegionInfo, Integer, List<ServerName>>(region, nodeVersion, favoredNodes)); } } // Move on to open regions. try { // Send OPEN RPC. If it fails on a IOE or RemoteException, // regions will be assigned individually. long maxWaitTime = System.currentTimeMillis() + this.server.getConfiguration() .getLong("hbase.regionserver.rpc.startup.waittime", 60000); for (int i = 1; i <= maximumAttempts && !server.isStopped(); i++) { try { List<RegionOpeningState> regionOpeningStateList = serverManager .sendRegionOpen(destination, regionOpenInfos); if (regionOpeningStateList == null) { // Failed getting RPC connection to this server return false; } for (int k = 0, n = regionOpeningStateList.size(); k < n; k++) { RegionOpeningState openingState = regionOpeningStateList.get(k); if (openingState != RegionOpeningState.OPENED) { HRegionInfo region = regionOpenInfos.get(k).getFirst(); if (openingState == RegionOpeningState.ALREADY_OPENED) { processAlreadyOpenedRegion(region, destination); } else if (openingState == RegionOpeningState.FAILED_OPENING) { // Failed opening this region, reassign it later failedToOpenRegions.add(region); } else { LOG.warn("THIS SHOULD NOT HAPPEN: unknown opening state " + openingState + " in assigning region " + region); } } } break; } catch (IOException e) { if (e instanceof RemoteException) { e = ((RemoteException) e).unwrapRemoteException(); } if (e instanceof RegionServerStoppedException) { LOG.warn("The region server was shut down, ", e); // No need to retry, the region server is a goner. return false; } else if (e instanceof ServerNotRunningYetException) { long now = System.currentTimeMillis(); if (now < maxWaitTime) { LOG.debug("Server is not yet up; waiting up to " + (maxWaitTime - now) + "ms", e); Thread.sleep(100); i--; // reset the try count continue; } } else if (e instanceof java.net.SocketTimeoutException && this.serverManager.isServerOnline(destination)) { // In case socket is timed out and the region server is still online, // the openRegion RPC could have been accepted by the server and // just the response didn't go through. So we will retry to // open the region on the same server. if (LOG.isDebugEnabled()) { LOG.debug("Bulk assigner openRegion() to " + destination + " has timed out, but the regions might" + " already be opened on it.", e); } continue; } throw e; } } } catch (IOException e) { // Can be a socket timeout, EOF, NoRouteToHost, etc LOG.info("Unable to communicate with " + destination + " in order to assign regions, ", e); return false; } } finally { for (Lock lock : locks.values()) { lock.unlock(); } } if (!failedToOpenRegions.isEmpty()) { for (HRegionInfo region : failedToOpenRegions) { if (!regionStates.isRegionOnline(region)) { invokeAssign(region); } } } LOG.debug("Bulk assigning done for " + destination); return true; } finally { metricsAssignmentManager.updateBulkAssignTime(EnvironmentEdgeManager.currentTimeMillis() - startTime); } }
From source file:jp.aegif.nemaki.cmis.service.impl.AclServiceImpl.java
@Override public Acl applyAcl(CallContext callContext, String repositoryId, String objectId, Acl acl, AclPropagation aclPropagation) { exceptionService.invalidArgumentRequired("objectId", objectId); Lock lock = threadLockService.getReadLock(repositoryId, objectId); try {/*from w w w .j a va 2s .c o m*/ lock.lock(); // ////////////////// // General Exception // ////////////////// Content content = contentService.getContent(repositoryId, objectId); exceptionService.objectNotFound(DomainType.OBJECT, content, objectId); exceptionService.permissionDenied(callContext, repositoryId, PermissionMapping.CAN_APPLY_ACL_OBJECT, content); // ////////////////// // Specific Exception // ////////////////// TypeDefinition td = typeManager.getTypeDefinition(repositoryId, content); if (!td.isControllableAcl()) exceptionService.constraint(objectId, "applyAcl cannot be performed on the object whose controllableAcl = false"); exceptionService.constraintAclPropagationDoesNotMatch(aclPropagation); exceptionService.constraintPermissionDefined(repositoryId, acl, objectId); // ////////////////// // Body of the method // ////////////////// //Check ACL inheritance boolean inherited = true; //Inheritance defaults to true if nothing input List<CmisExtensionElement> exts = acl.getExtensions(); if (!CollectionUtils.isEmpty(exts)) { for (CmisExtensionElement ext : exts) { if (ext.getName().equals("inherited")) { inherited = Boolean.valueOf(ext.getValue()); } } if (!contentService.getAclInheritedWithDefault(repositoryId, content).equals(inherited)) content.setAclInherited(inherited); } jp.aegif.nemaki.model.Acl nemakiAcl = new jp.aegif.nemaki.model.Acl(); //REPOSITORYDETERMINED or PROPAGATE is considered as PROPAGATE boolean objectOnly = (aclPropagation == AclPropagation.OBJECTONLY) ? true : false; for (Ace ace : acl.getAces()) { if (ace.isDirect()) { jp.aegif.nemaki.model.Ace nemakiAce = new jp.aegif.nemaki.model.Ace(ace.getPrincipalId(), ace.getPermissions(), objectOnly); nemakiAcl.getLocalAces().add(nemakiAce); } } convertSystemPrinciaplId(repositoryId, nemakiAcl); content.setAcl(nemakiAcl); contentService.update(repositoryId, content); contentService.writeChangeEvent(callContext, repositoryId, content, nemakiAcl, ChangeType.SECURITY); nemakiCachePool.get(repositoryId).removeCmisCache(objectId); clearCachesRecursively(Executors.newCachedThreadPool(), callContext, repositoryId, content, false); writeChangeEventsRecursively(Executors.newCachedThreadPool(), callContext, repositoryId, content, false); return getAcl(callContext, repositoryId, objectId, false); } finally { lock.unlock(); } }
From source file:org.pepstock.jem.node.persistence.RecoveryManager.java
/** * Applies all redo statements from Hazelcast map * @return true if apply statements/*from w ww. j a v a 2 s.c o m*/ * @throws MessageException if any errors occurs during the apply of redo statements * */ public boolean applyRedoStatements() throws MessageException { // gets the HC map IMap<Long, RedoStatement> redoMap = Main.getHazelcast().getMap(Queues.REDO_STATEMENT_MAP); // locks inetrnally of JEM cluster Lock lock = Main.getHazelcast().getLock(Queues.REDO_STATEMENT_MAP_LOCK); boolean isLock = false; try { // gets a lock isLock = lock.tryLock(10, TimeUnit.SECONDS); if (isLock) { // if map of redo statements is empty // means nothing to apply if (redoMap.isEmpty()) { return false; } // reads all redo statements List<RedoStatement> values = new ArrayList<RedoStatement>(redoMap.values()); // sorts by ID // in this ways it can apply all redo statements on the right order // how they have been created Collections.sort(values, new Comparator<RedoStatement>() { @Override public int compare(RedoStatement rd0, RedoStatement rd1) { return rd0.getId().compareTo(rd1.getId()); } }); // scans all redo statements for (RedoStatement statement : values) { // extracts the map store of HC // using the queue information of redo statement JobMapManager mapStore = null; if (statement.getQueueName().equalsIgnoreCase(Queues.INPUT_QUEUE)) { mapStore = InputMapManager.getInstance(); } else if (statement.getQueueName().equalsIgnoreCase(Queues.RUNNING_QUEUE)) { mapStore = RunningMapManager.getInstance(); } else if (statement.getQueueName().equalsIgnoreCase(Queues.OUTPUT_QUEUE)) { mapStore = OutputMapManager.getInstance(); } else if (statement.getQueueName().equalsIgnoreCase(Queues.ROUTING_QUEUE)) { mapStore = RoutingMapManager.getInstance(); } // if action is store, it calls the store method // of map store // otherwise it calls the delete one if (statement.getAction().equalsIgnoreCase(RedoStatement.STORE)) { mapStore.store(statement.getJob().getId(), statement.getJob(), true); } else if (statement.getAction().equalsIgnoreCase(RedoStatement.DELETE)) { mapStore.delete(statement.getJobId(), true); } // remove the redo statement from HC map redoMap.remove(statement.getId()); // shows the redo has been ended correctly LogAppl.getInstance().emit(NodeMessage.JEMC176I, statement.toString()); } LogAppl.getInstance().emit(NodeMessage.JEMC177I, String.valueOf(values.size())); // all redo has been done correctly return true; } else { throw new MessageException(NodeMessage.JEMC119E, Queues.REDO_STATEMENT_MAP); } } catch (Exception e) { throw new MessageException(NodeMessage.JEMC119E, e, Queues.REDO_STATEMENT_MAP); } finally { // always unlock the lock on REDO if (isLock) { lock.unlock(); } } }
From source file:com.threecrickets.prudence.cache.SqlCache.java
public CacheEntry fetch(String key) { Lock lock = lockSource.getReadLock(key); lock.lock();//from ww w. jav a2 s . c o m try { Connection connection = connect(); if (connection == null) return null; try { String sql = "SELECT data, media_type, language, character_set, encoding, modification_date, tag, headers, expiration_date, document_modification_date FROM " + cacheTableName + " WHERE key=?"; PreparedStatement statement = connection.prepareStatement(sql); try { statement.setString(1, key); ResultSet rs = statement.executeQuery(); try { if (rs.next()) { byte[] data = rs.getBytes(1); MediaType mediaType = MediaType.valueOf(rs.getString(2)); Language language = Language.valueOf(rs.getString(3)); CharacterSet characterSet = CharacterSet.valueOf(rs.getString(4)); Encoding encoding = Encoding.valueOf(rs.getString(5)); Timestamp modificationDate = rs.getTimestamp(6); String tagValue = rs.getString(7); Tag tag = tagValue != null ? Tag.parse(tagValue) : null; String rawHeaders = rs.getString(8); Series<Header> headers = (rawHeaders != null) && (rawHeaders.length() > 0) ? deserializeHeaders(rawHeaders) : null; Timestamp expirationDate = rs.getTimestamp(9); Timestamp documentModificationDate = rs.getTimestamp(10); logger.fine("Fetched: " + key); CacheEntry entry; if (encoding != null) entry = new CacheEntry(data, mediaType, language, characterSet, encoding, headers, modificationDate, tag, expirationDate, documentModificationDate); else { try { entry = new CacheEntry(new String(data), mediaType, language, characterSet, null, headers, modificationDate, tag, expirationDate, documentModificationDate); } catch (IOException x) { throw new RuntimeException("Should never happen if data is not encoded!"); } } if (new java.util.Date().after(entry.getExpirationDate())) { lock.unlock(); try { logger.fine("Stale entry: " + key); delete(connection, key); // (Note that this also discarded our lock, // but we kept it as a local variable) } finally { lock.lock(); } return null; } return entry; } } finally { rs.close(); } } finally { statement.close(); } } finally { connection.close(); } } catch (SQLException x) { logger.log(Level.WARNING, "Could not fetch cache entry", x); } finally { lock.unlock(); } logger.fine("Did not fetch: " + key); return null; }