List of usage examples for java.util.concurrent.atomic AtomicReference AtomicReference
public AtomicReference(V initialValue)
From source file:com.twitter.distributedlog.lock.TestZKSessionLock.java
private void testLockWhenSiblingUseDifferentLockId(long timeout, final boolean isUnlock) throws Exception { String lockPath = "/test-lock-when-sibling-use-different-lock-id-" + timeout + "-" + isUnlock + "-" + System.currentTimeMillis(); String clientId0 = "client-id-0"; String clientId1 = "client-id-1"; createLockPath(zkc.get(), lockPath); final ZKSessionLock lock0_0 = new ZKSessionLock(zkc0, lockPath, clientId0, lockStateExecutor); final ZKSessionLock lock0_1 = new ZKSessionLock(zkc0, lockPath, clientId0, lockStateExecutor); final ZKSessionLock lock1 = new ZKSessionLock(zkc, lockPath, clientId1, lockStateExecutor); lock0_0.tryLock(Long.MAX_VALUE, TimeUnit.MILLISECONDS); // lock1 wait for the lock ownership. final CountDownLatch lock1DoneLatch = new CountDownLatch(1); Thread lock1Thread = new Thread(new Runnable() { @Override/*from w w w .jav a 2 s.c om*/ public void run() { try { lock1.tryLock(Long.MAX_VALUE, TimeUnit.MILLISECONDS); lock1DoneLatch.countDown(); } catch (LockingException e) { logger.error("Failed on locking lock1 : ", e); } } }, "lock1-thread"); lock1Thread.start(); // check lock1 is waiting for lock0_0 List<String> children = awaitWaiters(2, zkc, lockPath); assertEquals(2, children.size()); assertEquals(State.CLAIMED, lock0_0.getLockState()); assertEquals(lock0_0.getLockId(), Await.result(asyncParseClientID(zkc0.get(), lockPath, children.get(0)))); awaitState(State.WAITING, lock1); assertEquals(lock1.getLockId(), Await.result(asyncParseClientID(zkc.get(), lockPath, children.get(1)))); final CountDownLatch lock0DoneLatch = new CountDownLatch(1); final AtomicReference<String> ownerFromLock0 = new AtomicReference<String>(null); Thread lock0Thread = null; if (timeout == 0) { try { lock0_1.tryLock(0, TimeUnit.MILLISECONDS); fail("Should fail on locking if sibling is using differnt lock id."); } catch (OwnershipAcquireFailedException oafe) { assertEquals(clientId0, oafe.getCurrentOwner()); } assertEquals(State.CLOSED, lock0_1.getLockState()); children = getLockWaiters(zkc, lockPath); assertEquals(2, children.size()); assertEquals(State.CLAIMED, lock0_0.getLockState()); assertEquals(lock0_0.getLockId(), Await.result(asyncParseClientID(zkc0.get(), lockPath, children.get(0)))); assertEquals(State.WAITING, lock1.getLockState()); assertEquals(lock1.getLockId(), Await.result(asyncParseClientID(zkc.get(), lockPath, children.get(1)))); } else { lock0Thread = new Thread(new Runnable() { @Override public void run() { try { lock0_1.tryLock(Long.MAX_VALUE, TimeUnit.MILLISECONDS); if (isUnlock) { lock0DoneLatch.countDown(); } } catch (OwnershipAcquireFailedException oafe) { if (!isUnlock) { ownerFromLock0.set(oafe.getCurrentOwner()); lock0DoneLatch.countDown(); } } catch (LockingException le) { logger.error("Failed on locking lock0_1 : ", le); } } }, "lock0-thread"); lock0Thread.start(); // check lock1 is waiting for lock0_0 children = awaitWaiters(3, zkc, lockPath); assertEquals(3, children.size()); assertEquals(State.CLAIMED, lock0_0.getLockState()); assertEquals(lock0_0.getLockId(), Await.result(asyncParseClientID(zkc0.get(), lockPath, children.get(0)))); awaitState(State.WAITING, lock1); assertEquals(lock1.getLockId(), Await.result(asyncParseClientID(zkc.get(), lockPath, children.get(1)))); awaitState(State.WAITING, lock0_1); assertEquals(lock0_1.getLockId(), Await.result(asyncParseClientID(zkc0.get(), lockPath, children.get(2)))); } if (isUnlock) { lock0_0.unlock(); } else { ZooKeeperClientUtils.expireSession(zkc0, zkServers, sessionTimeoutMs); } lock1DoneLatch.await(); lock1Thread.join(); // check the state of lock0_0 if (isUnlock) { assertEquals(State.CLOSED, lock0_0.getLockState()); } else { assertEquals(State.EXPIRED, lock0_0.getLockState()); } if (timeout == 0) { children = getLockWaiters(zkc, lockPath); assertEquals(1, children.size()); assertEquals(State.CLAIMED, lock1.getLockState()); assertEquals(lock1.getLockId(), Await.result(asyncParseClientID(zkc.get(), lockPath, children.get(0)))); } else { assertNotNull(lock0Thread); if (!isUnlock) { // both lock0_0 and lock0_1 would be expired lock0DoneLatch.await(); lock0Thread.join(); assertEquals(clientId0, ownerFromLock0.get()); assertEquals(State.CLOSED, lock0_1.getLockState()); children = getLockWaiters(zkc, lockPath); assertEquals(1, children.size()); assertEquals(State.CLAIMED, lock1.getLockState()); assertEquals(lock1.getLockId(), Await.result(asyncParseClientID(zkc.get(), lockPath, children.get(0)))); } else { children = getLockWaiters(zkc, lockPath); assertEquals(2, children.size()); assertEquals(State.CLAIMED, lock1.getLockState()); assertEquals(lock1.getLockId(), Await.result(asyncParseClientID(zkc.get(), lockPath, children.get(0)))); assertEquals(State.WAITING, lock0_1.getLockState()); assertEquals(lock0_1.getLockId(), Await.result(asyncParseClientID(zkc0.get(), lockPath, children.get(1)))); } } lock1.unlock(); if (timeout != 0 && isUnlock) { lock0DoneLatch.await(); lock0Thread.join(); children = getLockWaiters(zkc, lockPath); assertEquals(1, children.size()); assertEquals(State.CLAIMED, lock0_1.getLockState()); assertEquals(lock0_1.getLockId(), Await.result(asyncParseClientID(zkc0.get(), lockPath, children.get(0)))); } }
From source file:com.google.gdt.eclipse.designer.util.Utils.java
/** * @return the default locale from "set-property-fallback" property in module file. *//* w w w . ja va 2 s . co m*/ public static String getDefaultLocale(ModuleDescription moduleDescription) throws Exception { final AtomicReference<String> defaultLocale = new AtomicReference<String>("default"); ModuleVisitor.accept(moduleDescription, new ModuleVisitor() { @Override public void endVisitModule(ModuleElement module) { List<SetPropertyFallbackElement> elements = module.getSetPropertyFallbackElements(); for (SetPropertyFallbackElement element : elements) { if (element.getName().equals("locale")) { defaultLocale.set(element.getValue()); } } } }); return defaultLocale.get(); }
From source file:com.microsoft.tfs.core.clients.versioncontrol.internal.localworkspace.LocalDataAccessLayer.java
/** * * * * @param workspace//from w w w. j ava 2 s. c o m * @param lv * @param pc * @param changeRequests * @param silent * @param failures * @param onlineOperationRequired * @param invalidateWorkspaceAfterServerCall * @return */ public static GetOperation[] pendRename(final Workspace workspace, final LocalWorkspaceProperties wp, final WorkspaceVersionTable lv, final LocalPendingChangesTable pc, final ChangeRequest[] changeRequests, final boolean silent, final AtomicReference<Failure[]> failures, final AtomicBoolean onlineOperationRequired, final String[] itemPropertyFilters) { Check.notNull(workspace, "workspace"); //$NON-NLS-1$ Check.notNull(changeRequests, "changeRequests"); //$NON-NLS-1$ workspace.getWorkspaceWatcher().scan(wp, lv, pc); final List<Failure> failureList = new ArrayList<Failure>(); final List<GetOperation> getOps = new ArrayList<GetOperation>(); failures.set(null); final WorkingFolder[] workspaceMappings = wp.getWorkingFolders(); for (int i = 0; i < changeRequests.length; i++) { if (null == changeRequests[i]) { continue; } final ParsedItemSpec parsedItemSpec = ParsedItemSpec.fromItemSpec(changeRequests[i].getItemSpec(), wp, lv, pc, ParsedItemSpecOptions.NONE, failureList); if (null == parsedItemSpec) { continue; } final String sourceRoot = parsedItemSpec.getTargetItem(); String targetRoot = changeRequests[i].getTargetItem(); final String sourceServerRoot = tryGetServerItem(sourceRoot, wp, lv, pc); String targetServerRoot = null; boolean isCloaked = false; if (ServerPath.isServerPath(targetRoot)) { targetServerRoot = targetRoot; } else { final PathTranslation translation = WorkingFolder.translateLocalItemToServerItem(targetRoot, workspaceMappings); if (translation != null) { targetServerRoot = translation.getTranslatedPath(); isCloaked = translation.isCloaked(); } } if (isCloaked) { failureList.add(createItemCloakedFailure(targetRoot)); continue; } else if (targetServerRoot == null) { // Error is consistent with server workspaces when target path // is non-server and unmapped, but not cloaked failureList.add(createItemNotMappedFailure(targetRoot)); continue; } final String targetLocalRoot = ServerPath.isServerPath(targetRoot) ? WorkingFolder.getLocalItemForServerItem(targetRoot, workspaceMappings) : targetRoot; final int maxServerPathLength = workspace.getClient().getMaxServerPathLength(); // For consistency in error messages with server workspaces, check // the provided itemspec first, then the translated path. final AtomicReference<String> outTargetRoot = new AtomicReference<String>(targetRoot); ItemPath.checkItem(outTargetRoot, "changeRequest.ItemSpec.Item", //$NON-NLS-1$ false, false, false, true, maxServerPathLength); targetRoot = outTargetRoot.get(); if (ServerPath.isServerPath(targetRoot)) { if (targetLocalRoot != null && targetLocalRoot.length() > 0) { LocalPath.checkLocalItem(targetLocalRoot, "TargetItem", false, false, false, true); //$NON-NLS-1$ } } else { final AtomicReference<String> outTargetServerRoot = new AtomicReference<String>(targetServerRoot); ServerPath.checkServerItem(outTargetServerRoot, "TargetItem", //$NON-NLS-1$ false, false, false, true, maxServerPathLength); targetServerRoot = outTargetServerRoot.get(); } // server path minus all renames that exists on its parents final String targetUnrenamedServerRoot = pc.getCommittedServerItemForTargetServerItem(targetServerRoot); if (ItemPath.isWildcard(targetRoot)) { failureList.add( new Failure(Messages.getString("LocalDataAccessLayer.WildcardNotAllowedForRenameTarget"), //$NON-NLS-1$ FailureCodes.WILDCARD_NOT_ALLOWED_EXCEPTION, SeverityType.ERROR, targetRoot)); continue; } final ItemType targetItemType = changeRequests[i].getTargetItemType(); final boolean isMove = isMove(targetUnrenamedServerRoot, targetItemType, lv); final boolean targetIsFolder = targetItemType == ItemType.ANY ? isDirectory(lv, pc, targetServerRoot) : targetItemType == ItemType.FOLDER; // if we move dir\*.cs, root (dir will not be included), if we move // dir, root is included final boolean rootIncludedInRename = parsedItemSpec.getPattern() == null; if (parsedItemSpec.getPattern() != null && ItemPath.isWildcard(parsedItemSpec.getPattern()) && !isMove) { failureList.add( new Failure(Messages.getString("LocalDataAccessLayer.WildcardNotAllowedForRenameSource"), //$NON-NLS-1$ FailureCodes.WILDCARD_NOT_ALLOWED_EXCEPTION, SeverityType.ERROR, sourceRoot)); continue; } if (ServerPath.isRootFolder(targetServerRoot)) { failureList .add(new Failure(Messages.getString("LocalDataAccessLayer.CanNotChangeRootFolderException"), //$NON-NLS-1$ FailureCodes.CANNOT_CHANGE_ROOT_FOLDER_EXCEPTION, SeverityType.ERROR, parsedItemSpec.getTargetItem())); continue; } if (!targetIsFolder) { // we validate if target is a team project only if it doesn't // exist in local workspace - if it does, we will move files // under it final Failure teamProjectValidationFailure = TeamProject.validateChange(targetServerRoot, ItemType.FOLDER); if (teamProjectValidationFailure != null) { failureList.add(teamProjectValidationFailure); continue; } } for (final WorkspaceLocalItem lvEntry : parsedItemSpec.expandFrom(lv, pc, failureList)) { final String sourceCommittedServerItem = lvEntry.getServerItem(); String sourceCurrentServerItem = sourceCommittedServerItem; if (lvEntry.isCommitted()) { sourceCurrentServerItem = pc .getTargetServerItemForCommittedServerItem(sourceCommittedServerItem); } final String targetServerItem = calculateTargetServerItem(sourceServerRoot, sourceCurrentServerItem, targetServerRoot, targetIsFolder, rootIncludedInRename); // targetLocalItem may be null if we move file into not mapped // location final String targetLocalItem = WorkingFolder.getLocalItemForServerItem(targetServerItem, wp.getWorkingFolders()); final boolean caseOnlyRename = ServerPath.equals(sourceCurrentServerItem, targetServerItem) && !ServerPath.equals(sourceCurrentServerItem, targetServerItem, false); if (ServerPath.isRootFolder(sourceCurrentServerItem)) { failureList.add( new Failure(Messages.getString("LocalDataAccessLayer.CanNotChangeRootFolderException"), //$NON-NLS-1$ FailureCodes.CANNOT_CHANGE_ROOT_FOLDER_EXCEPTION, SeverityType.ERROR, sourceCurrentServerItem)); continue; } final Failure teamProjectValidationFailure = TeamProject.validateChange(sourceCommittedServerItem, lvEntry.isDirectory() ? ItemType.FOLDER : ItemType.FILE); if (teamProjectValidationFailure != null) { failureList.add(teamProjectValidationFailure); continue; } if (targetServerItem.length() > VersionControlConstants.MAX_SERVER_PATH_SIZE) { failureList.add(createPathTooLongFailure(targetServerItem)); continue; } // validate mappings boolean workspaceMappingFailure = false; for (final WorkingFolder mapping : workspaceMappings) { if (ServerPath.equals(mapping.getServerItem(), sourceCurrentServerItem)) { final String format = Messages .getString("LocalDataAccessLayer.RenameWorkingFolderExceptionFormat"); //$NON-NLS-1$ failureList.add(new Failure(MessageFormat.format(format, sourceCurrentServerItem), FailureCodes.RENAME_WORKING_FOLDER_EXCEPTION, SeverityType.ERROR, sourceCurrentServerItem)); workspaceMappingFailure = true; break; } if (ServerPath.isChild(sourceCurrentServerItem, mapping.getServerItem())) { return sendToServer(failures, onlineOperationRequired); } } if (workspaceMappingFailure) { continue; } if (!caseOnlyRename && pc.getByTargetServerItem(targetServerItem) != null) { final String format = Messages .getString("LocalDataAccessLayer.ChangeAlreadyPendingExceptionFormat"); //$NON-NLS-1$ failureList.add(new Failure(MessageFormat.format(format, targetServerItem), FailureCodes.CHANGE_ALREADY_PENDING_EXCEPTION, SeverityType.ERROR, sourceCurrentServerItem)); continue; } if (pc.getRecursiveChangeTypeForTargetServerItem(targetServerItem).contains(ChangeType.DELETE)) { failureList.add(createPendingParentDeleteFailure(targetServerItem)); continue; } LocalPendingChange mainPendingChange = pc.getByLocalVersion(lvEntry); if (null != mainPendingChange) { if (mainPendingChange.isLock()) { // Cannot offline rename a pending lock. return sendToServer(failures, onlineOperationRequired); } if (mainPendingChange.isDelete()) { final String format = Messages .getString("LocalDataAccessLayer.IncompatibleChangeExceptionFormat"); //$NON-NLS-1$ failureList.add(new Failure(MessageFormat.format(format, targetServerItem), FailureCodes.INCOMPATIBLE_CHANGE_EXCEPTION, SeverityType.ERROR, changeRequests[i].getItemSpec().getItem())); continue; } // target server item minus all parent renames // if we have both parent renamed (folder->folder2) and item // renamed(a->b), renaming folder2\a to folder2\b // should undo rename on bar final String targetParent = ServerPath.getParent(targetServerItem); final String committedParent = pc.getCommittedServerItemForTargetServerItem(targetParent); String targetUnrenamedParent = null; if (committedParent != null && committedParent.length() > 0) { targetUnrenamedParent = committedParent + targetServerItem.substring(targetParent.length()); } if ((targetUnrenamedParent != null && ServerPath.equals(targetUnrenamedParent, sourceCommittedServerItem, false)) || ServerPath.equals(sourceCommittedServerItem, targetServerItem, false)) { // Selective undo final AtomicReference<Failure[]> undoFailures = new AtomicReference<Failure[]>(); final List<LocalPendingChange> changes = new ArrayList<LocalPendingChange>(); changes.add(mainPendingChange); final GetOperation[] undoOps = undoPendingChanges(workspace, wp, lv, pc, changes, ChangeType.RENAME, undoFailures, onlineOperationRequired); if (onlineOperationRequired.get()) { return sendToServer(failures, onlineOperationRequired); } failureList.addAll(Arrays.asList(undoFailures.get())); getOps.addAll(Arrays.asList(undoOps)); continue; } } WorkspaceLocalItem conflictingItem = (targetLocalItem == null || targetLocalItem.length() == 0) ? null : lv.getByLocalItem(targetLocalItem); if (conflictingItem != null && !caseOnlyRename) { final String format = Messages.getString("LocalDataAccessLayer.ItemExistsExceptionFormat"); //$NON-NLS-1$ failureList.add(new Failure(MessageFormat.format(format, targetServerItem), FailureCodes.ITEM_EXISTS_EXCEPTION, SeverityType.ERROR, conflictingItem.getLocalItem())); continue; } final List<GetOperation> affectedItems = new ArrayList<GetOperation>(); final Map<String, LocalPendingChange> affectedCommittedPendingChanges = new HashMap<String, LocalPendingChange>(); final Map<String, LocalPendingChange> affectedNotCommittedPendingChanges = new HashMap<String, LocalPendingChange>(); // we should not updated pending changes in the main loop, since // we use them to calculate target path for each item // we need to do that afterwards final List<KeyValuePair<String, LocalPendingChange>> updatedPendingChanges = new ArrayList<KeyValuePair<String, LocalPendingChange>>(); // Create or update main pending change (on the item itself) if (mainPendingChange == null) { mainPendingChange = new LocalPendingChange(lvEntry, targetServerItem, ChangeType.RENAME); affectedCommittedPendingChanges.put(mainPendingChange.getCommittedServerItem(), mainPendingChange); } else { if (mainPendingChange.isAdd() || mainPendingChange.isBranch()) { affectedNotCommittedPendingChanges.put(mainPendingChange.getTargetServerItem(), mainPendingChange); } else { mainPendingChange .setChangeType(mainPendingChange.getChangeType().combine(ChangeType.RENAME)); affectedCommittedPendingChanges.put(mainPendingChange.getCommittedServerItem(), mainPendingChange); } } boolean abort = false; if (lvEntry.isDirectory()) { // build lookup of pending changes, so we can update them // and populate GetOps with the right change for (final LocalPendingChange lpEntry : pc.queryByTargetServerItem(sourceCurrentServerItem, RecursionType.FULL, "*")) //$NON-NLS-1$ { if (lpEntry.isAdd() || lpEntry.isBranch()) { affectedNotCommittedPendingChanges.put(lpEntry.getTargetServerItem(), lpEntry); } else { affectedCommittedPendingChanges.put(lpEntry.getCommittedServerItem(), lpEntry); } } } for (final WorkspaceLocalItem childEntry : ParsedItemSpec.queryLocalVersionsByTargetServerItem(lv, pc, sourceCurrentServerItem, RecursionType.FULL, null, ParsedItemSpecOptions.INCLUDE_DELETED)) { String childTargetServerItem; GetOperation childGetOp; LocalPendingChange associatedPendingChange = null; if (childEntry.isCommitted()) { associatedPendingChange = affectedCommittedPendingChanges.get(childEntry.getServerItem()); } else if (!childEntry.isCommitted()) { associatedPendingChange = affectedNotCommittedPendingChanges .get(childEntry.getServerItem()); } if (associatedPendingChange != null) { if (associatedPendingChange.isLock()) { // Cannot offline rename a pending lock. return sendToServer(failures, onlineOperationRequired); } if (!ServerPath.equals(targetServerItem, associatedPendingChange.getTargetServerItem(), false)) { // do not update if this is new pending change we // just created (mainPendingChange) childTargetServerItem = calculateTargetServerItem(sourceServerRoot, associatedPendingChange.getTargetServerItem(), targetServerRoot, targetIsFolder, rootIncludedInRename); } else { childTargetServerItem = associatedPendingChange.getTargetServerItem(); } updatedPendingChanges.add(new KeyValuePair<String, LocalPendingChange>( childTargetServerItem, associatedPendingChange)); childGetOp = childEntry.toGetOperation(associatedPendingChange, itemPropertyFilters); // SourceServerItem should be identical with // TargetServerItem for not committed changes (add and // branch) childGetOp.setSourceServerItem(childEntry.isCommitted() ? childGetOp.getSourceServerItem() : childTargetServerItem); childGetOp.setTargetServerItem(childTargetServerItem); childGetOp.setChangeType(childEntry.isCommitted() ? associatedPendingChange.getChangeType().combine(ChangeType.RENAME) : childGetOp.getChangeType()); } else { final String currentServerItem = childEntry.isCommitted() ? pc.getTargetServerItemForCommittedServerItem(childEntry.getServerItem()) : childEntry.getServerItem(); childTargetServerItem = calculateTargetServerItem(sourceServerRoot, currentServerItem, targetServerRoot, targetIsFolder, rootIncludedInRename); childGetOp = childEntry.toGetOperation(itemPropertyFilters); childGetOp.setTargetServerItem(childTargetServerItem); childGetOp.setChangeType(ChangeType.RENAME); } // TODO we include deletes only to add entry to // updatedPendingChanges and update them later. We should // check how costly it is when we rename folder that // contains big deletes subfolder if (childEntry.isDeleted()) { continue; } if (childTargetServerItem.length() > VersionControlConstants.MAX_SERVER_PATH_SIZE) { abort = true; failureList.add(createPathTooLongFailure(childTargetServerItem)); break; } final String childTargetLocalItem = WorkingFolder .getLocalItemForServerItem(childTargetServerItem, wp.getWorkingFolders()); conflictingItem = (childTargetLocalItem == null || childTargetLocalItem.length() == 0) ? null : lv.getByLocalItem(childTargetLocalItem); if (conflictingItem != null && !ServerPath.equals(conflictingItem.getServerItem(), childEntry.getServerItem())) { abort = true; final String format = Messages.getString("LocalDataAccessLayer.ItemExistsExceptionFormat"); //$NON-NLS-1$ failureList.add(new Failure(MessageFormat.format(format, targetServerItem), FailureCodes.ITEM_EXISTS_EXCEPTION, SeverityType.ERROR, conflictingItem.getLocalItem())); break; } if ((childTargetLocalItem == null || childTargetLocalItem.length() == 0) && childGetOp.getChangeType().contains(ChangeType.EDIT)) { abort = true; final String format = Messages .getString("LocalDataAccessLayer.TargetCloakedExceptionFormat"); //$NON-NLS-1$ failureList.add(new Failure(MessageFormat.format(format, sourceCurrentServerItem), FailureCodes.TARGET_CLOAKED_EXCEPTION, SeverityType.ERROR, sourceCurrentServerItem)); break; } if (silent) { // we generated all possible warnings, now bail since // it's a silent operation continue; } childGetOp.setTargetLocalItem(childTargetLocalItem); affectedItems.add(childGetOp); } if (abort) { continue; } // update pending changes for (final KeyValuePair<String, LocalPendingChange> updatedPendingChangeInfo : updatedPendingChanges) { final String updateServerPath = updatedPendingChangeInfo.getKey(); final LocalPendingChange updatedPendingChange = updatedPendingChangeInfo.getValue(); pc.remove(updatedPendingChange); updatedPendingChange.setTargetServerItem(updateServerPath); pc.pendChange(updatedPendingChange); } if (!silent) { // update local versions of not committed items (adds and // branches) for (final String originalServerItem : affectedNotCommittedPendingChanges.keySet()) { final LocalPendingChange pendingChange = affectedNotCommittedPendingChanges .get(originalServerItem); final WorkspaceLocalItem addEntry = lv.getByServerItem(originalServerItem, false); if (addEntry != null) { lv.removeByServerItem(originalServerItem, false, true); addEntry.setServerItem(pendingChange.getTargetServerItem()); // TODO what about renaming pending branch into not // mapped location? // TODO we already calculated this local path once, // we should store it in // affectedNotCommittedPendingChanges and reuse it addEntry.setLocalItem(WorkingFolder.getLocalItemForServerItem( pendingChange.getTargetServerItem(), wp.getWorkingFolders())); lv.add(addEntry); } } } getOps.addAll(affectedItems); } } for (final Failure failure : failureList) { failure.setRequestType(RequestType.RENAME); } onlineOperationRequired.set(false); failures.set(failureList.toArray(new Failure[failureList.size()])); return getOps.toArray(new GetOperation[getOps.size()]); }
From source file:github.daneren2005.dsub.service.RESTMusicService.java
private HttpResponse executeWithRetry(Context context, String url, String originalUrl, HttpParams requestParams, List<String> parameterNames, List<Object> parameterValues, List<Header> headers, ProgressListener progressListener, CancellableTask task) throws IOException { // Strip out sensitive information from log Log.i(TAG, "Using URL " + url.substring(0, url.indexOf("?u=") + 1) + url.substring(url.indexOf("&v=") + 1)); SharedPreferences prefs = Util.getPreferences(context); int networkTimeout = Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_NETWORK_TIMEOUT, "15000")); HttpParams newParams = httpClient.getParams(); HttpConnectionParams.setSoTimeout(newParams, networkTimeout); httpClient.setParams(newParams);//www . j av a 2 s. c o m final AtomicReference<Boolean> cancelled = new AtomicReference<Boolean>(false); int attempts = 0; while (true) { attempts++; HttpContext httpContext = new BasicHttpContext(); final HttpPost request = new HttpPost(url); if (task != null) { // Attempt to abort the HTTP request if the task is cancelled. task.setOnCancelListener(new CancellableTask.OnCancelListener() { @Override public void onCancel() { new Thread(new Runnable() { public void run() { try { cancelled.set(true); request.abort(); } catch (Exception e) { Log.e(TAG, "Failed to stop http task"); } } }).start(); } }); } if (parameterNames != null) { List<NameValuePair> params = new ArrayList<NameValuePair>(); for (int i = 0; i < parameterNames.size(); i++) { params.add( new BasicNameValuePair(parameterNames.get(i), String.valueOf(parameterValues.get(i)))); } request.setEntity(new UrlEncodedFormEntity(params, Constants.UTF_8)); } if (requestParams != null) { request.setParams(requestParams); Log.d(TAG, "Socket read timeout: " + HttpConnectionParams.getSoTimeout(requestParams) + " ms."); } if (headers != null) { for (Header header : headers) { request.addHeader(header); } } // Set credentials to get through apache proxies that require authentication. int instance = prefs.getInt(Constants.PREFERENCES_KEY_SERVER_INSTANCE, 1); String username = prefs.getString(Constants.PREFERENCES_KEY_USERNAME + instance, null); String password = prefs.getString(Constants.PREFERENCES_KEY_PASSWORD + instance, null); httpClient.getCredentialsProvider().setCredentials( new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), new UsernamePasswordCredentials(username, password)); try { HttpResponse response = httpClient.execute(request, httpContext); detectRedirect(originalUrl, context, httpContext); return response; } catch (IOException x) { request.abort(); if (attempts >= HTTP_REQUEST_MAX_ATTEMPTS || cancelled.get()) { throw x; } if (progressListener != null) { String msg = context.getResources().getString(R.string.music_service_retry, attempts, HTTP_REQUEST_MAX_ATTEMPTS - 1); progressListener.updateProgress(msg); } Log.w(TAG, "Got IOException (" + attempts + "), will retry", x); increaseTimeouts(requestParams); Util.sleepQuietly(2000L); } } }
From source file:com.alibaba.wasp.master.FMaster.java
/** * * @param tableName//from ww w. j a va 2 s.co m * @param rowKey * @return * @throws java.io.IOException */ public Pair<EntityGroupInfo, ServerName> getTableEntityGroupForRow(final byte[] tableName, final byte[] rowKey) throws IOException { final AtomicReference<Pair<EntityGroupInfo, ServerName>> result = new AtomicReference<Pair<EntityGroupInfo, ServerName>>( null); MetaScannerVisitor visitor = new MetaScannerVisitorBase() { @Override public boolean processRow(Result data) throws IOException { if (data == null || data.size() <= 0) { return true; } Pair<EntityGroupInfo, ServerName> pair = EntityGroupInfo.getEntityGroupInfoAndServerName(data); if (pair == null) { return false; } if (!Bytes.equals(pair.getFirst().getTableName(), tableName)) { return false; } result.set(pair); return true; } }; FMetaScanner.metaScan(conf, visitor, tableName, rowKey, 1); return result.get(); }
From source file:com.alibaba.wasp.master.FMaster.java
/** * @see com.alibaba.wasp.protobuf.generated.MasterAdminProtos.MasterAdminService.BlockingInterface#getEntityGroupWithScan(com.google.protobuf.RpcController, * com.alibaba.wasp.protobuf.generated.MasterAdminProtos.GetEntityGroupWithScanRequest) *//*from w ww . j a v a 2s . c om*/ @Override public GetEntityGroupWithScanResponse getEntityGroupWithScan(RpcController controller, GetEntityGroupWithScanRequest request) throws ServiceException { byte[] tableNameOrEntityGroupName = request.getTableNameOrEntityGroupName().toByteArray(); Pair<EntityGroupInfo, ServerName> pair; try { pair = FMetaReader.getEntityGroup(conf, tableNameOrEntityGroupName); if (pair == null) { final AtomicReference<Pair<EntityGroupInfo, ServerName>> result = new AtomicReference<Pair<EntityGroupInfo, ServerName>>( null); final String encodedName = Bytes.toString(tableNameOrEntityGroupName); MetaScannerVisitor visitor = new MetaScannerVisitorBase() { @Override public boolean processRow(org.apache.hadoop.hbase.client.Result data) throws IOException { EntityGroupInfo info = EntityGroupInfo.getEntityGroupInfo(data); if (info == null) { LOG.warn("No serialized EntityGroupInfo in " + data); return true; } if (!encodedName.equals(info.getEncodedName())) { return true; } ServerName sn = EntityGroupInfo.getServerName(data); result.set(new Pair<EntityGroupInfo, ServerName>(info, sn)); return false; // found the entityGroup, stop } }; FMetaScanner.metaScan(conf, visitor); pair = result.get(); } GetEntityGroupWithScanResponse.Builder builder = GetEntityGroupWithScanResponse.newBuilder(); if (pair != null) { if (pair.getFirst() != null) { builder.setEgInfo(pair.getFirst().convert()); } if (pair.getSecond() != null) { builder.setServerName(pair.getSecond().convert()); } } return builder.build(); } catch (Exception e) { LOG.error("Failed getEntityGroupWithScan.", e); throw new ServiceException(e); } }
From source file:com.mellanox.r4h.DFSOutputStream.java
protected DFSOutputStream(DFSClient dfsClient, String src, Progressable progress, HdfsFileStatus stat, DataChecksum checksum) throws IOException { super(getChecksum4Compute(checksum, stat)); this.dfsClient = dfsClient; this.src = src; this.fileId = stat.getFileId(); this.blockSize = stat.getBlockSize(); this.blockReplication = stat.getReplication(); this.fileEncryptionInfo = stat.getFileEncryptionInfo(); this.progress = progress; this.cachingStrategy = new AtomicReference<CachingStrategy>(dfsClient.getDefaultWriteCachingStrategy()); this.jxioResource = dfsClient.getJXIOResource(); this.usingJxioClientResource = true; this.eventQHandler = jxioResource.getEqh(); this.msgPool = jxioResource.getMsgPool(); this.headerAckTimeoutUsec = dfsClient.getConf().getHeaderAckTimeoutUsec(); if ((progress != null) && DFSOutputStream.LOG.isDebugEnabled()) { DFSOutputStream.LOG.debug("Set non-null progress callback on DFSOutputStream " + src); }/*from w w w. j a v a2 s . c o m*/ this.bytesPerChecksum = checksum.getBytesPerChecksum(); if (bytesPerChecksum < 1 || blockSize % bytesPerChecksum != 0) { throw new IOException("io.bytes.per.checksum(" + bytesPerChecksum + ") and blockSize(" + blockSize + ") do not match. " + "blockSize should be a " + "multiple of io.bytes.per.checksum"); } this.name = String.format("[hash=%X] ", DFSOutputStream.this.hashCode()); this.checksum = checksum; if (toPrintBreakdown) { long now = System.nanoTime(); DFSOutputStream.LOG.info(String.format("%.3f", (float) now / 1000000000.) + ", " + (now - lastOperationTS) / 1000000000. + " : DFSOutputStream constructed successfully."); synchronized (lastOperationTSLock) { lastOperationTS = now; } // } else { // LOG.info("Mellanox RDMA-accelerated DFSOutputStream constructed successfully."); } }
From source file:com.microsoft.tfs.core.clients.versioncontrol.internal.localworkspace.LocalDataAccessLayer.java
private static boolean reconcileLocalWorkspaceHelper(final Workspace workspace, final WebServiceLayer webServiceLayer, final boolean unscannedReconcile, final boolean reconcileMissingFromDisk, final AtomicReference<Failure[]> failures, final AtomicBoolean pendingChangesUpdatedByServer) { Check.notNull(workspace, "workspace"); //$NON-NLS-1$ pendingChangesUpdatedByServer.set(false); final List<PendingChange> convertedAdds = new ArrayList<PendingChange>(); final boolean throwOnProjectRenamed; if (EnvironmentVariables.isDefined(EnvironmentVariables.DD_SUITES_PROJECT_RENAME_UNPATCHED_CLIENT)) { throwOnProjectRenamed = false;/*from w w w. j av a2 s.c o m*/ } else { throwOnProjectRenamed = true; } final AtomicReference<GUID> serverPendingChangeSignature = new AtomicReference<GUID>(GUID.EMPTY); // No optimization away of reconciles when sending up MissingFromDisk // rows, since the bit in the header (lvHeader.PendingReconcile) may be // false when we actually have work to do (there are rows in the table // marked MissingFromDisk). if ((unscannedReconcile || !workspace.getWorkspaceWatcher().isScanNecessary()) && !reconcileMissingFromDisk) { // Pre-reconcile final AtomicBoolean hasPendingLocalVersionRows = new AtomicBoolean(true); LocalWorkspaceTransaction transaction = new LocalWorkspaceTransaction(workspace); try { transaction.execute(new LocalVersionHeaderTransaction() { @Override public void invoke(final WorkspaceVersionTableHeader lvh) { hasPendingLocalVersionRows.set(lvh.getPendingReconcile()); } }); } finally { try { transaction.close(); } catch (final IOException e) { throw new VersionControlException(e); } } final AtomicReference<GUID> clientPendingChangeSignature = new AtomicReference<GUID>(GUID.EMPTY); if (!hasPendingLocalVersionRows.get()) { transaction = new LocalWorkspaceTransaction(workspace); try { transaction.execute(new PendingChangesHeaderTransaction() { @Override public void invoke(final LocalPendingChangesTableHeader pch) { clientPendingChangeSignature.set(pch.getClientSignature()); } }); } finally { try { transaction.close(); } catch (final IOException e) { throw new VersionControlException(e); } } final GUID lastServerPendingChangeGuid = workspace.getOfflineCacheData() .getLastServerPendingChangeSignature(); final Calendar lastReconcileTime = workspace.getOfflineCacheData().getLastReconcileTime(); lastReconcileTime.add(Calendar.SECOND, 8); if (lastServerPendingChangeGuid != GUID.EMPTY && clientPendingChangeSignature.get().equals(lastServerPendingChangeGuid) && lastReconcileTime.after(Calendar.getInstance())) { // This reconcile was optimized away with no server call. failures.set(new Failure[0]); return false; } serverPendingChangeSignature.set( webServiceLayer.queryPendingChangeSignature(workspace.getName(), workspace.getOwnerName())); if (serverPendingChangeSignature.get() != GUID.EMPTY && clientPendingChangeSignature.get().equals(serverPendingChangeSignature)) { // This reconcile was optimized away. workspace.getOfflineCacheData() .setLastServerPendingChangeSignature(serverPendingChangeSignature.get()); workspace.getOfflineCacheData().setLastReconcileTime(Calendar.getInstance()); failures.set(new Failure[0]); return false; } } } final AtomicBoolean toReturn = new AtomicBoolean(true); final LocalWorkspaceTransaction transaction = new LocalWorkspaceTransaction(workspace); try { final AtomicReference<Failure[]> delegateFailures = new AtomicReference<Failure[]>(new Failure[0]); final AtomicBoolean delegatePCUpdated = new AtomicBoolean(false); transaction.execute(new AllTablesTransaction() { @Override public void invoke(final LocalWorkspaceProperties wp, final WorkspaceVersionTable lv, final LocalPendingChangesTable pc) { if (!unscannedReconcile) { // The line below has been commented out because we // decided not to force a full scan here, because it // causes significant degradation in UI performance. // // workspace.getWorkspaceWatcher().markPathChanged(null); // // It was an attempt to fix the bug: // Bug 6191: When using local workspaces, get latest // does not get a file that has been deleted from disk. // // The customer has to explicitly invoke // Pending Changes>Actions>Detect local changes // in Team Explorer. // // Note that none of customers reported that as an // issue. // It was detected on our tests only. workspace.getWorkspaceWatcher().scan(wp, lv, pc); } // Pre-reconcile if (!lv.getPendingReconcile() && !reconcileMissingFromDisk && GUID.EMPTY == serverPendingChangeSignature.get()) { serverPendingChangeSignature.set(webServiceLayer .queryPendingChangeSignature(workspace.getName(), workspace.getOwnerName())); if (serverPendingChangeSignature.get() != GUID.EMPTY && pc.getClientSignature().equals(serverPendingChangeSignature.get())) { // This reconcile was optimized away. delegateFailures.set(new Failure[0]); workspace.getOfflineCacheData() .setLastServerPendingChangeSignature(serverPendingChangeSignature.get()); workspace.getOfflineCacheData().setLastReconcileTime(Calendar.getInstance()); toReturn.set(true); return; } } // Acknowledgment of team project renames, if any have been // completed if (wp.getNewProjectRevisionId() > 0) { webServiceLayer.promotePendingWorkspaceMappings(workspace.getName(), workspace.getOwnerName(), wp.getNewProjectRevisionId()); wp.setNewProjectRevisionId(0); } final LocalPendingChange[] pendingChanges = pc.queryByTargetServerItem(ServerPath.ROOT, RecursionType.FULL, null); /* * TEE-specific Code * * In order to support offline property changes, which * cannot be reconciled with * WebServiceLayer.reconcileLocalWorkspace (the property * values can't be sent), we have to pull out the pended * property changes and send them to the server before * reconciling. */ final List<ChangeRequest> propertyRequests = new ArrayList<ChangeRequest>(); for (final LocalPendingChange lpc : pendingChanges) { if (lpc.getChangeType().contains(ChangeType.PROPERTY)) { final PropertyValue[] pv = lpc.getPropertyValues(); final String serverItem = lpc.getTargetServerItem(); if (pv != null && pv.length > 0 && serverItem != null) { final ChangeRequest request = new ChangeRequest( new ItemSpec(serverItem, RecursionType.NONE), new WorkspaceVersionSpec(workspace), RequestType.PROPERTY, ItemType.ANY, VersionControlConstants.ENCODING_UNCHANGED, LockLevel.UNCHANGED, 0, null, false); request.setProperties(pv); propertyRequests.add(request); } } } if (propertyRequests.size() > 0) { ((WebServiceLayerLocalWorkspaces) webServiceLayer).pendChangesInLocalWorkspace( workspace.getName(), workspace.getOwnerName(), propertyRequests.toArray(new ChangeRequest[propertyRequests.size()]), PendChangesOptions.NONE, SupportedFeatures.ALL, new AtomicReference<Failure[]>(), null, null, new AtomicBoolean(), new AtomicReference<ChangePendedFlags>()); // TODO handle failures? } // Back to normal, non-TEE behavior final AtomicBoolean outClearLocalVersionTable = new AtomicBoolean(); final ServerItemLocalVersionUpdate[] lvUpdates = lv.getUpdatesForReconcile(pendingChanges, reconcileMissingFromDisk, outClearLocalVersionTable); ReconcileResult result = webServiceLayer.reconcileLocalWorkspace(workspace.getName(), workspace.getOwnerName(), pc.getClientSignature(), pendingChanges, lvUpdates, outClearLocalVersionTable.get(), throwOnProjectRenamed); // report any failures Failure[] reconcileFailures = result.getFailures(); workspace.getClient().reportFailures(workspace, reconcileFailures); if (reconcileFailures.length > 0) { throw new ReconcileFailedException(reconcileFailures); } GUID newSignature = new GUID(result.getNewSignature()); PendingChange[] newPendingChanges = result.getNewPendingChanges(); // If the local version rows for this local workspace have // been purged from the server, then the server will set // this flag on the result of the next reconcile. if (result.isReplayLocalVersionsRequired()) { // Reconcile a second time. This time, set the // clearLocalVersionTable flag. This way, we know // we have cleared out any lingering local version rows // for this workspace. if (!outClearLocalVersionTable.get()) { result = webServiceLayer.reconcileLocalWorkspace(workspace.getName(), workspace.getOwnerName(), pc.getClientSignature(), pendingChanges, lvUpdates, true /* clearLocalVersionTable */, throwOnProjectRenamed); // Report any failures reconcileFailures = result.getFailures(); workspace.getClient().reportFailures(workspace, reconcileFailures); if (reconcileFailures.length > 0) { throw new ReconcileFailedException(reconcileFailures); } // Grab the new signature and new pending changes newSignature = new GUID(result.getNewSignature()); newPendingChanges = result.getNewPendingChanges(); } // Now, go through the local version table and replay // every row that we have. final List<ServerItemLocalVersionUpdate> replayUpdates = new ArrayList<ServerItemLocalVersionUpdate>( Math.min(lv.getLocalItemsCount(), 1000)); for (final WorkspaceLocalItem lvEntry : lv.queryByServerItem(ServerPath.ROOT, RecursionType.FULL, null, true /* includeDeleted */)) { final ServerItemLocalVersionUpdate replayUpdate = lvEntry .getLocalVersionUpdate(reconcileMissingFromDisk, true /* force */); if (replayUpdate != null) { replayUpdates.add(replayUpdate); // Batch these updates in groups of 1000 items. if (replayUpdates.size() >= 1000) { webServiceLayer.updateLocalVersion(workspace.getName(), workspace.getOwnerName(), replayUpdates.toArray( new ServerItemLocalVersionUpdate[replayUpdates.size()])); replayUpdates.clear(); } } } if (replayUpdates.size() > 0) { webServiceLayer.updateLocalVersion(workspace.getName(), workspace.getOwnerName(), replayUpdates.toArray(new ServerItemLocalVersionUpdate[replayUpdates.size()])); } } if (result.isPendingChangesUpdated()) { delegatePCUpdated.set(true); final Map<String, ItemType> newPendingDeletes = new TreeMap<String, ItemType>( String.CASE_INSENSITIVE_ORDER); for (final PendingChange pendingChange : newPendingChanges) { if (pendingChange.isAdd()) { final LocalPendingChange oldPendingChange = pc .getByTargetServerItem(pendingChange.getServerItem()); if (null == oldPendingChange || !oldPendingChange.isAdd()) { // Before calling ReconcileLocalWorkspace, // we did not have a pending add at this // target server item. convertedAdds.add(pendingChange); } } else if (pendingChange.isDelete()) { // If the server removed any of our presented // pending deletes, we want to know about it so // we can get rid of the local version rows that // we have in the deleted state. The server will // remove our pending deletes when the item has // been destroyed on the server. newPendingDeletes.put( pendingChange.getSourceServerItem() == null ? pendingChange.getServerItem() : pendingChange.getSourceServerItem(), pendingChange.getItemType()); } } for (final LocalPendingChange oldPendingChange : pc .queryByCommittedServerItem(ServerPath.ROOT, RecursionType.FULL, null)) { if (oldPendingChange.isDelete() && !newPendingDeletes.containsKey(oldPendingChange.getCommittedServerItem())) { // We presented this delete to the server for // Reconcile, but the server removed it from the // pending changes manifest. We need to get rid // of the LV rows for // oldPendingChange.CommittedServerItem since // this item is now destroyed. final List<ServerItemIsCommittedTuple> lvRowsToRemove = new ArrayList<ServerItemIsCommittedTuple>(); final RecursionType recursion = oldPendingChange.isRecursiveChange() ? RecursionType.FULL : RecursionType.NONE; // Aggregate up the deleted local version // entries at this committed server item // (or below if it's a folder), and we'll remove // them. for (final WorkspaceLocalItem lvEntry : lv.queryByServerItem( oldPendingChange.getCommittedServerItem(), recursion, null, true /* includeDeleted */)) { if (lvEntry.isDeleted()) { lvRowsToRemove.add(new ServerItemIsCommittedTuple(lvEntry.getServerItem(), lvEntry.isCommitted())); } } for (final ServerItemIsCommittedTuple tuple : lvRowsToRemove) { // We don't need to reconcile the removal of // LV entries marked IsDeleted since they // don't exist on the server anyway. lv.removeByServerItem(tuple.getCommittedServerItem(), tuple.isCommitted(), false); } } } pc.replacePendingChanges(newPendingChanges); } // If all we're doing to LV is marking it reconciled, then // don't use TxF to commit // both tables atomically as this is slower if (!lv.isDirty()) { transaction.setAllowTxF(false); } if (lvUpdates.length > 0) { lv.markAsReconciled(wp, reconcileMissingFromDisk); // If we removed all missing-from-disk items from the // local version table, then we need to remove // the corresponding candidate delete rows for those // items as well. if (reconcileMissingFromDisk) { List<String> candidatesToRemove = null; for (final LocalPendingChange candidateChange : pc .queryCandidatesByTargetServerItem(ServerPath.ROOT, RecursionType.FULL, null)) { if (candidateChange.isDelete()) { if (null == candidatesToRemove) { candidatesToRemove = new ArrayList<String>(); } candidatesToRemove.add(candidateChange.getTargetServerItem()); } } if (null != candidatesToRemove) { for (final String candidateDeleteTargetServerItem : candidatesToRemove) { pc.removeCandidateByTargetServerItem(candidateDeleteTargetServerItem); } // Set the candidates changed to true so that it // refreshes the UI LocalWorkspaceTransaction.getCurrent().setRaisePendingChangeCandidatesChanged(true); } } } newSignature = webServiceLayer.queryPendingChangeSignature(workspace.getName(), workspace.getOwnerName()); if (!newSignature.equals(pc.getClientSignature())) { pc.setClientSignature(newSignature); workspace.getOfflineCacheData().setLastServerPendingChangeSignature(newSignature); } if (!newSignature.equals(pc.getClientSignature())) { pc.setClientSignature(newSignature); workspace.getOfflineCacheData().setLastServerPendingChangeSignature(newSignature); } workspace.getOfflineCacheData().setLastReconcileTime(Calendar.getInstance()); } }); failures.set(delegateFailures.get()); pendingChangesUpdatedByServer.set(delegatePCUpdated.get()); } finally { try { transaction.close(); } catch (final IOException e) { throw new VersionControlException(e); } } if (convertedAdds.size() > 0) { final UpdateLocalVersionQueueOptions options = UpdateLocalVersionQueueOptions.UPDATE_BOTH; final UpdateLocalVersionQueue ulvq = new UpdateLocalVersionQueue(workspace, options); try { for (final PendingChange pc : convertedAdds) { // Every item in this list has a ChangeType of Add. As a // result they are uncommitted items with no committed hash // value, no committed length, and no baseline file GUID. ulvq.queueUpdate(new ClientLocalVersionUpdate(pc.getServerItem(), pc.getItemID(), pc.getLocalItem(), 0 /* localVersion */, DotNETDate.MIN_CALENDAR, pc.getEncoding(), null /* committedHashValue */, 0 /* committedLength */, null /* baselineFileGuid */, null /* pendingChangeTargetServerItem */, null /* properties */)); } } finally { ulvq.close(); } } return toReturn.get(); }
From source file:com.microsoft.tfs.core.clients.versioncontrol.internal.localworkspace.LocalDataAccessLayer.java
/** * Retrieves the authoritative copy of the working folders for a local * workspace.//from w w w. j a v a 2 s. com * * * @param workspace * The local workspace whose working folders should be fetched * @return The working folders for the local workspace */ public static WorkingFolder[] queryWorkingFolders(final Workspace workspace) { final AtomicReference<WorkingFolder[]> toReturn = new AtomicReference<WorkingFolder[]>(null); final LocalWorkspaceTransaction transaction = new LocalWorkspaceTransaction(workspace); try { transaction.execute(new WorkspacePropertiesTransaction() { @Override public void invoke(final LocalWorkspaceProperties wp) { // Make a deep copy to return to the caller. toReturn.set(WorkingFolder.clone(wp.getWorkingFolders())); } }); } finally { try { transaction.close(); } catch (final IOException e) { throw new VersionControlException(e); } } return toReturn.get(); }