final long start = System.currentTimeMillis();
// because we are outside realm of nexus here, we need to handle locking ourselves...
final RepositoryItemUid repoUid = repository.createUid(P2Constants.METADATA_LOCK_PATH);
final RepositoryItemUidLock repoLock = repoUid.getLock();
// needed to give away the lock on actual metadata file (content.xml or artifact.xml) as we will regenerate it
final RepositoryItemUid itemUid = repository.createUid(request.getRequestPath());
final RepositoryItemUidLock itemLock = itemUid.getLock();
// start with read lock, no need to do a write lock until we find it necessary
try {
repoLock.lock(Action.read);
if (P2Constants.CONTENT_XML.equals(request.getRequestPath())
|| P2Constants.CONTENT_JAR.equals(request.getRequestPath())) {
try {
final AbstractStorageItem contentItem = doRetrieveLocalItem(request, repository);
if (request.isRequestLocalOnly() || !isContentOld(contentItem, repository)) {
return contentItem;
}
}
catch (final ItemNotFoundException e) {
// fall through
}
// give away the lock on content.xml as we will regenerate it
itemLock.unlock();
try {
// we need to get new file, so update the lock
repoLock.lock(Action.delete);
// recheck the condition now that we have an exclusive lock
try {
final AbstractStorageItem contentItem = doRetrieveLocalItem(request, repository);
if (!isContentOld(contentItem, repository)) {
return contentItem;
}
}
catch (final ItemNotFoundException e) {
// fall through
}
try {
final StorageItem result = doRetrieveContentItems(request.getRequestContext(), repository).get(
request.getRequestPath()
);
doRetrieveArtifactsItems(request.getRequestContext(), repository);
return result;
}
catch (final P2RuntimeExceptionMaskedAsINFException e) {
return doRetrieveLocalOnTransferError(request, repository, e);
}
}
finally {
// release repo
repoLock.unlock();
// get back the lock we gave in
itemLock.lock(Action.read);
}
}
else if (P2Constants.ARTIFACTS_XML.equals(request.getRequestPath())
|| P2Constants.ARTIFACTS_JAR.equals(request.getRequestPath())) {
try {
final AbstractStorageItem artifactsItem = doRetrieveLocalItem(request, repository);
if (request.isRequestLocalOnly() || !isArtifactsOld(artifactsItem, repository)) {
return artifactsItem;
}
}
catch (final ItemNotFoundException e) {
// fall through
}
// give away the lock on artifacts.xml as we will regenerate it
itemLock.unlock();
try {
// we need to get new file, so update the lock
repoLock.lock(Action.delete);
// recheck the condition now that we have an exclusive lock
try {
final AbstractStorageItem artifactsItem = doRetrieveLocalItem(request, repository);
if (!isArtifactsOld(artifactsItem, repository)) {
return artifactsItem;
}
}
catch (final ItemNotFoundException e) {
// fall through
}
try {
deleteItemSilently(repository, new ResourceStoreRequest(P2Constants.PRIVATE_ROOT));
doRetrieveContentItems(request.getRequestContext(), repository);
return doRetrieveArtifactsItems(request.getRequestContext(), repository).get(request.getRequestPath());
}
catch (final P2RuntimeExceptionMaskedAsINFException e) {
return doRetrieveLocalOnTransferError(request, repository, e);
}
}
finally {
// release repo
repoLock.unlock();
// get back the lock we gave in
itemLock.lock(Action.read);
}
}
// we explicitly do not serve any other metadata files
throw new ItemNotFoundException(request, repository);