Example usage for java.util.concurrent.atomic AtomicBoolean set

List of usage examples for java.util.concurrent.atomic AtomicBoolean set

Introduction

In this page you can find the example usage for java.util.concurrent.atomic AtomicBoolean set.

Prototype

public final void set(boolean newValue) 

Source Link

Document

Sets the value to newValue , with memory effects as specified by VarHandle#setVolatile .

Usage

From source file:com.microsoft.tfs.core.clients.versioncontrol.soapextensions.Workspace.java

/**
 * Reconciles a local workspace with the server.
 *
 *
 * @param reconcileMissingLocalItems/*  w w  w . j  a  va 2  s. c  om*/
 *        True to remove local version rows for items that no longer exist
 *        on disk
 * @param AtomicBboolean
 */
public void reconcile(final boolean reconcileMissingLocalItems,
        final AtomicBoolean pendingChangesUpdatedByServer) {
    pendingChangesUpdatedByServer.set(false);
    if (WorkspaceLocation.LOCAL != this.getLocation()) {
        // No work to do.
        return;
    }

    final AtomicReference<Failure[]> failures = new AtomicReference<Failure[]>();

    LocalDataAccessLayer.reconcileLocalWorkspace(this, client.getWebServiceLayer(), false,
            reconcileMissingLocalItems, failures, pendingChangesUpdatedByServer);

    client.reportFailures(this, failures.get());
}

From source file:com.microsoft.tfs.core.clients.versioncontrol.soapextensions.Workspace.java

/**
 * Calculates set of paths, used for querying conflicts.
 *
 * @param getRequests//from w ww.  j  ava2 s.  co  m
 *        paths specified by the user
 * @param writableConflictPaths
 *        paths of files causing SourceWritable or TargetWritable conflicts
 * @param recursive
 *        recursive if the conflict query needs to be recursive
 * @return List of paths to query
 */
private String[] calculateConflictScope(final GetRequest[] getRequests, final String[] writableConflictPaths,
        final AtomicBoolean recursive) {
    recursive.set(false);

    final List<String> result = new ArrayList<String>();

    /* Always query for all paths specified by the user. */
    for (final GetRequest getRequest : getRequests) {
        if (getRequest.getItemSpec() == null) {
            /* This is a workspace get so just query all conflicts. */
            return null;
        }

        /*
         * If we see any full recursion then we mark this request as
         * recursive.
         */
        if (RecursionType.FULL.equals(getRequest.getItemSpec().getRecursionType())) {
            recursive.set(true);
        }

        final String path = getRequest.getItemSpec().getItem();
        if (RecursionType.ONE_LEVEL.equals(getRequest.getItemSpec().getRecursionType())) {
            /*
             * We can make QueryConflicts one level, ending it with *. It's
             * incorrect to have local path with multiple *, so we append it
             * only when there is none, both for local and server path.
             */
            if (path.indexOf('*') == -1) {
                if (ServerPath.isServerPath(path)) {
                    result.add(ServerPath.combine(path, "*")); //$NON-NLS-1$
                } else {
                    result.add(LocalPath.combine(path, "*")); //$NON-NLS-1$
                }
            }
        }

        /*
         * Even if we added one-level recursion path with *, we need to add
         * path itself as well because $/tp/a/* does not include $/tp/a
         * itself, but one level get on $/tp/a does.
         */
        result.add(path);
    }

    if (writableConflictPaths != null) {
        /*
         * Now let's add source path of files causing SourceWritable or
         * TargetWritable conflicts that are not rooted in the paths
         * specified by the user.
         */
        for (final String sourcePath : writableConflictPaths) {
            boolean includePath = true;
            for (final GetRequest getRequest : getRequests) {
                final String getRequestPath = getRequest.getItemSpec().getItem();

                /*
                 * sourcePath is a local path so we call IsSubItem only if
                 * getRequestPath is local path as well.
                 */
                if (getRequestPath != null && getRequestPath.length() > 0
                        && !ServerPath.isServerPath(getRequestPath)
                        && LocalPath.isChild(getRequestPath, sourcePath)) {
                    includePath = false;
                    break;
                }
            }
            if (includePath) {
                result.add(sourcePath);
            }
        }
    }

    return result.toArray(new String[result.size()]);
}

From source file:org.apache.hadoop.hive.metastore.ObjectStore.java

protected boolean getPartitionsByExprInternal(String dbName, String tblName, final byte[] expr,
        final String defaultPartitionName, final short maxParts, List<Partition> result, boolean allowSql,
        boolean allowJdo) throws TException {
    assert result != null;
    final ExpressionTree exprTree = PartFilterExprUtil.makeExpressionTree(expressionProxy, expr);
    final AtomicBoolean hasUnknownPartitions = new AtomicBoolean(false);
    result.addAll(new GetListHelper<Partition>(dbName, tblName, allowSql, allowJdo) {
        @Override//  w w  w .j av a 2  s . c om
        protected List<Partition> getSqlResult(GetHelper<List<Partition>> ctx) throws MetaException {
            // If we have some sort of expression tree, try SQL filter pushdown.
            List<Partition> result = null;
            if (exprTree != null) {
                SqlFilterForPushdown filter = new SqlFilterForPushdown();
                if (directSql.generateSqlFilterForPushdown(ctx.getTable(), exprTree, filter)) {
                    return directSql.getPartitionsViaSqlFilter(filter, null);
                }
            }
            // We couldn't do SQL filter pushdown. Get names via normal means.
            List<String> partNames = new LinkedList<String>();
            hasUnknownPartitions.set(getPartitionNamesPrunedByExprNoTxn(ctx.getTable(), expr,
                    defaultPartitionName, maxParts, partNames));
            return directSql.getPartitionsViaSqlFilter(dbName, tblName, partNames);
        }

        @Override
        protected List<Partition> getJdoResult(GetHelper<List<Partition>> ctx)
                throws MetaException, NoSuchObjectException {
            // If we have some sort of expression tree, try JDOQL filter pushdown.
            List<Partition> result = null;
            if (exprTree != null) {
                result = getPartitionsViaOrmFilter(ctx.getTable(), exprTree, maxParts, false);
            }
            if (result == null) {
                // We couldn't do JDOQL filter pushdown. Get names via normal means.
                List<String> partNames = new ArrayList<String>();
                hasUnknownPartitions.set(getPartitionNamesPrunedByExprNoTxn(ctx.getTable(), expr,
                        defaultPartitionName, maxParts, partNames));
                result = getPartitionsViaOrmFilter(dbName, tblName, partNames);
            }
            return result;
        }
    }.run(true));
    return hasUnknownPartitions.get();
}

From source file:com.screenslicer.webapp.ScreenSlicerClient.java

@Path("create")
@POST//  w ww .ja  v  a  2  s  .  c  om
@Consumes("application/json")
@Produces("application/json")
public static final Response create(String reqString) {
    if (reqString != null) {
        final String reqDecoded = Crypto.decode(reqString, CommonUtil.ip());
        if (reqDecoded != null) {
            final Map<String, Object> args = CommonUtil.gson.fromJson(reqDecoded, CommonUtil.objectType);
            final Request request = CommonUtil.gson.fromJson(reqDecoded, Request.class);
            Field[] fields = request.getClass().getFields();
            for (Field field : fields) {
                args.remove(field.getName());
            }
            new Thread(new Runnable() {
                @Override
                public void run() {
                    String myInstance = null;
                    AtomicBoolean myDone = null;
                    try {
                        CommonFile.writeStringToFile(
                                new File("./data/" + request.runGuid + "-meta" + request.appId),
                                request.jobId + "\n" + request.jobGuid + "\n"
                                        + Calendar.getInstance(TimeZone.getTimeZone("GMT")).getTimeInMillis(),
                                false);
                        CommonFile.writeStringToFile(new File("./data/" + request.runGuid + "-context"),
                                Crypto.encode(reqDecoded), false);
                        Map<String, AtomicBoolean> myDoneMap = new HashMap<String, AtomicBoolean>();
                        synchronized (doneMapLock) {
                            for (int i = 0; i < request.instances.length; i++) {
                                if (!doneMap.containsKey(request.instances[i])) {
                                    doneMap.put(request.instances[i], new AtomicBoolean(true));
                                }
                            }
                            myDoneMap.putAll(doneMap);
                        }
                        long myThread = latestThread.incrementAndGet();
                        while (true) {
                            if (isCancelled(request.runGuid)) {
                                curThread.incrementAndGet();
                                throw new CancellationException();
                            }
                            if (myThread == curThread.get() + 1) {
                                for (Map.Entry<String, AtomicBoolean> done : myDoneMap.entrySet()) {
                                    if (done.getValue().compareAndSet(true, false)) {
                                        if (ScreenSlicer.isBusy(done.getKey())) {
                                            done.getValue().set(true);
                                        } else {
                                            myInstance = done.getKey();
                                            myDone = done.getValue();
                                            break;
                                        }
                                    }
                                }
                                if (myInstance != null) {
                                    break;
                                }
                            }
                            try {
                                Thread.sleep(WAIT);
                            } catch (Exception e) {
                                Log.exception(e);
                            }
                        }
                        curThread.incrementAndGet();
                        int outputNumber = 0;
                        request.instances = new String[] { myInstance };
                        Map<String, List<List<String>>> tables = customApp.tableData(request, args);
                        Map<String, Map<String, Object>> jsons = customApp.jsonData(request, args);
                        Map<String, byte[]> binaries = customApp.binaryData(request, args);
                        request.emailExport.attachments = new LinkedHashMap<String, byte[]>();
                        if (tables != null) {
                            for (Map.Entry<String, List<List<String>>> table : tables.entrySet()) {
                                if (table.getKey().toLowerCase().endsWith(".xls")) {
                                    byte[] result = Spreadsheet.xls(table.getValue());
                                    CommonFile.writeByteArrayToFile(
                                            new File("./data/" + request.runGuid + "-result" + outputNumber),
                                            result, false);
                                    CommonFile.writeStringToFile(
                                            new File("./data/" + request.runGuid + "-result-names"),
                                            escapeName(table.getKey()) + "\n", true);
                                    ++outputNumber;
                                    if (request.emailResults) {
                                        request.emailExport.attachments.put(table.getKey(), result);
                                    }
                                } else if (table.getKey().toLowerCase().endsWith(".csv")) {
                                    String result = Spreadsheet.csv(table.getValue());
                                    CommonFile.writeStringToFile(
                                            new File("./data/" + request.runGuid + "-result" + outputNumber),
                                            result, false);
                                    CommonFile.writeStringToFile(
                                            new File("./data/" + request.runGuid + "-result-names"),
                                            escapeName(table.getKey()) + "\n", true);
                                    ++outputNumber;
                                    if (request.emailResults) {
                                        request.emailExport.attachments.put(table.getKey(),
                                                result.getBytes("utf-8"));
                                    }
                                } else if (table.getKey().toLowerCase().endsWith(".xcsv")) {
                                    String result = Spreadsheet.csv(table.getValue());
                                    CommonUtil.internalHttpCall(CommonUtil.ip(),
                                            "https://" + CommonUtil.ip() + ":8000/_/"
                                                    + Crypto.fastHash(table.getKey() + ":" + request.runGuid),
                                            "PUT", CommonUtil.asMap("Content-Type", "text/csv; charset=utf-8"),
                                            result.getBytes("utf-8"), null);
                                    CommonFile.writeStringToFile(
                                            new File("./data/" + request.runGuid + "-result-names"),
                                            escapeName(table.getKey()) + "\n", true);
                                    ++outputNumber;
                                    if (request.emailResults) {
                                        request.emailExport.attachments.put(table.getKey(),
                                                result.getBytes("utf-8"));
                                    }
                                } else {
                                    String result = CommonUtil.gson.toJson(table.getValue(),
                                            table.getValue().getClass());
                                    CommonFile.writeStringToFile(
                                            new File("./data/" + request.runGuid + "-result" + outputNumber),
                                            result, false);
                                    CommonFile.writeStringToFile(
                                            new File("./data/" + request.runGuid + "-result-names"),
                                            escapeName(table.getKey()) + "\n", true);
                                    ++outputNumber;
                                    if (request.emailResults) {
                                        request.emailExport.attachments.put(table.getKey(),
                                                result.getBytes("utf-8"));
                                    }
                                }
                            }
                        }
                        if (jsons != null) {
                            for (Map.Entry<String, Map<String, Object>> json : jsons.entrySet()) {
                                String result = CommonUtil.gson.toJson(json.getValue(), CommonUtil.objectType);
                                CommonFile.writeStringToFile(
                                        new File("./data/" + request.runGuid + "-result" + outputNumber),
                                        result, false);
                                CommonFile.writeStringToFile(
                                        new File("./data/" + request.runGuid + "-result-names"),
                                        escapeName(json.getKey()) + "\n", true);
                                ++outputNumber;
                                if (request.emailResults) {
                                    request.emailExport.attachments.put(json.getKey(),
                                            result.getBytes("utf-8"));
                                }
                            }
                        }
                        if (binaries != null) {
                            for (Map.Entry<String, byte[]> binary : binaries.entrySet()) {
                                CommonFile.writeByteArrayToFile(
                                        new File("./data/" + request.runGuid + "-result" + outputNumber),
                                        binary.getValue(), false);
                                CommonFile.writeStringToFile(
                                        new File("./data/" + request.runGuid + "-result-names"),
                                        escapeName(binary.getKey()) + "\n", true);
                                ++outputNumber;
                                if (request.emailResults) {
                                    request.emailExport.attachments.put(binary.getKey(), binary.getValue());
                                }
                            }
                        }
                        if (request.emailResults) {
                            ScreenSlicer.export(request, request.emailExport);
                        }
                    } catch (Throwable t) {
                        Log.exception(t);
                    } finally {
                        try {
                            CommonFile.writeStringToFile(
                                    new File("./data/" + request.runGuid + "-meta" + request.appId),
                                    "\n" + Calendar.getInstance(TimeZone.getTimeZone("GMT")).getTimeInMillis(),
                                    true);
                        } catch (Throwable t) {
                            Log.exception(t);
                        }
                        myDone.set(true);
                        synchronized (cancelledLock) {
                            cancelledJobs.remove(request.runGuid);
                        }
                    }
                }
            }).start();
            return Response.ok(Crypto.encode(request.runGuid, CommonUtil.ip())).build();
        }
    }
    return null;
}

From source file:Distortions.java

/**
 * Calculate each sensor correction increment for geometry and photometry contributed by all images selected in a series
 * @param selectedImages process only selected images 
 * @param showIndividual show per-image intermediate results
 * @param threadsMax maximal number of concurrent threads
 * @param updateStatus update IJ status/progress
 * @param debugLevel debug level/*from ww  w . j a v a 2 s . c  o  m*/
 * @return [sensor]{dpX,dpY,alpha,R,G,B}[pixelIndex] . dpX, dpY - correction to previous, RGB - total FF, not increment! 
 */

public double[][][] allImagesCorrectionMapped(final boolean[] selectedImages, final boolean showIndividual,
        final int showIndividualNumber, final int threadsMax, final boolean updateStatus,
        final int debugLevel) {
    int numChannels = fittingStrategy.distortionCalibrationData.getNumChannels(); // number of used channels
    final double[][][] gridPCorr = new double[numChannels][][];
    for (int chnNum = 0; chnNum < gridPCorr.length; chnNum++)
        gridPCorr[chnNum] = null;
    int numSelected = 0;
    for (int imgNum = 0; imgNum < selectedImages.length; imgNum++)
        if (selectedImages[imgNum])
            numSelected++;
    final int finalSelected = numSelected;
    if (updateStatus)
        IJ.showStatus("Calculating sensor corrections...");
    final AtomicInteger imageNumberAtomic = new AtomicInteger(0);
    final AtomicInteger imageFinishedAtomic = new AtomicInteger(0);
    final Thread[] threads = newThreadArray(threadsMax);
    final AtomicInteger stopRequested = this.stopRequested;
    final AtomicBoolean interruptedAtomic = new AtomicBoolean();
    final int alphaIndex = 2;

    for (int ithread = 0; ithread < threads.length; ithread++) {
        threads[ithread] = new Thread() {
            public void run() {
                for (int imgNum = imageNumberAtomic.getAndIncrement(); (imgNum < selectedImages.length)
                        && !interruptedAtomic.get(); imgNum = imageNumberAtomic.getAndIncrement()) {
                    if (selectedImages[imgNum]) {
                        int chnNum = fittingStrategy.distortionCalibrationData.gIP[imgNum].channel; // number of sub-camera
                        double[][] singleCorr = singleImageCorrectionMapped(imgNum, // image number
                                showIndividual
                                        && ((showIndividualNumber < 0) || (showIndividualNumber == chnNum)),
                                debugLevel);
                        combineImageCorrection(chnNum, gridPCorr, singleCorr);
                        final int numFinished = imageFinishedAtomic.getAndIncrement();
                        SwingUtilities.invokeLater(new Runnable() {
                            public void run() {
                                if (updateStatus)
                                    IJ.showProgress(numFinished, finalSelected);
                            }
                        });
                        if (stopRequested.get() == 1) { // ASAP
                            interruptedAtomic.set(true);
                        }
                    } //if (selectedImages[numImage]){
                } // for (int numImage=imageNumberAtomic.getAndIncrement(); ...
            } // public void run() {
        };
    }
    startAndJoin(threads);
    // divide by weight;
    for (int nChn = 0; nChn < gridPCorr.length; nChn++)
        if (gridPCorr[nChn] != null) {
            for (int i = 0; i < gridPCorr[nChn].length; i++) {
                if (i != alphaIndex) {
                    for (int j = 0; j < gridPCorr[nChn][i].length; j++) {
                        if (gridPCorr[nChn][alphaIndex][j] > 0)
                            gridPCorr[nChn][i][j] /= gridPCorr[nChn][alphaIndex][j];
                    }
                }
            }
        }

    if (updateStatus)
        IJ.showProgress(0);

    if (interruptedAtomic.get()) {
        System.out.println("allImagesCorrection() aborted by user request");
        return null;
    }
    return gridPCorr;
}

From source file:Distortions.java

public LMAArrays calculateJacobianArrays(final boolean[] selectedImages, // selected images to process
        final double[] Y, // should be initialized 
        final double[] fX, // should be initialized to correct length, data is not needed
        final double[] vector, // parameters vector
        final int[] imageStartIndex, // index of the first point of each image (including extra element in the end so n+1 is always valid)
        final double[][] patternXYZ, // this.targetXYZ
        final double[] weightFunction, // may be null - make it twice smaller? - same for X and Y?
        final LensDistortionParameters lensDistortionParametersProto,
        //         final double lambda,
        int threadsMax, boolean updateStatus) {

    // calculate JtJ
    //      double [] diff=calcYminusFx(fX);
    //      int numPars=this.jacobian.length; // number of parameters to be adjusted
    final int numPars = vector.length; // number of parameters to be adjusted
    //      int length=diff.length; // should be the same as this.jacobian[0].length 
    //      final int length=fX.length; // should be the same as this.jacobian[0].length 
    final double[][] JtByJmod = new double[numPars][numPars]; //Transposed Jacobian multiplied by Jacobian
    final double[] JtByDiff = new double[numPars];
    for (int i = 0; i < numPars; i++) {
        JtByDiff[i] = 0.0;/*from  www  . j av a2s  .  c  o  m*/
        for (int j = 0; j < numPars; j++)
            JtByJmod[i][j] = 0.0;
    }
    final int debugLevel = this.debugLevel;
    final Thread[] threads = newThreadArray(threadsMax);
    final AtomicInteger imageNumberAtomic = new AtomicInteger(0);
    final AtomicInteger imageFinishedAtomic = new AtomicInteger(0);
    final double[] progressValues = new double[selectedImages.length];
    int numSelectedImages = 0;
    for (int i = 0; i < selectedImages.length; i++)
        if (selectedImages[i])
            numSelectedImages++;
    int selectedIndex = 0;
    for (int i = 0; i < selectedImages.length; i++) {
        progressValues[i] = (selectedIndex + 1.0) / numSelectedImages;
        if (selectedImages[i])
            selectedIndex++;
        if (selectedIndex >= numSelectedImages)
            selectedIndex--;
    }
    final AtomicInteger stopRequested = this.stopRequested;
    final AtomicBoolean interruptedAtomic = new AtomicBoolean();
    for (int ithread = 0; ithread < threads.length; ithread++) {
        threads[ithread] = new Thread() {
            public void run() {
                LensDistortionParameters lensDistortionParameters = lensDistortionParametersProto.clone(); // see - if that is needed - maybe new is OK
                //                  LensDistortionParameters lensDistortionParameters= new LensDistortionParameters();
                for (int numImage = imageNumberAtomic.getAndIncrement(); (numImage < selectedImages.length)
                        && !interruptedAtomic.get(); numImage = imageNumberAtomic.getAndIncrement()) {
                    double[][] partialJacobian = calculatePartialFxAndJacobian(numImage, // number of grid image
                            vector, // parameters vector
                            patternXYZ, // this.targetXYZ
                            fX, // non-overlapping segments will be filled
                            imageStartIndex, // start index in patternXYZ array (length - difference to the next, includes extra last element)
                            lensDistortionParameters, // initialize one per each tread? Or for each call?
                            true); // when false, modifies only this.lensDistortionParameters.*

                    int length = 2 * (imageStartIndex[numImage + 1] - imageStartIndex[numImage]);
                    int start = 2 * imageStartIndex[numImage];

                    double[][] partialJtByJmod = new double[numPars][numPars]; // out of heap space
                    double[] partialJtByDiff = new double[numPars];

                    for (int i = 0; i < numPars; i++)
                        if (partialJacobian[i] != null) {
                            for (int j = i; j < numPars; j++)
                                if (partialJacobian[j] != null) {
                                    partialJtByJmod[i][j] = 0.0;
                                    if (weightFunction != null) {
                                        for (int k = 0; k < length; k++)
                                            partialJtByJmod[i][j] += partialJacobian[i][k]
                                                    * partialJacobian[j][k] * weightFunction[start + k];
                                    } else {
                                        for (int k = 0; k < length; k++)
                                            partialJtByJmod[i][j] += partialJacobian[i][k]
                                                    * partialJacobian[j][k];
                                    }
                                }
                        }

                    double[] partialDiff = new double[length];
                    for (int k = 0; k < length; k++)
                        partialDiff[k] = Y[start + k] - fX[start + k];

                    for (int i = 0; i < numPars; i++)
                        if (partialJacobian[i] != null) {
                            partialJtByDiff[i] = 0.0;
                            if (weightFunction != null)
                                for (int k = 0; k < length; k++)
                                    partialJtByDiff[i] += partialJacobian[i][k] * partialDiff[k]
                                            * weightFunction[start + k];
                            else
                                for (int k = 0; k < length; k++)
                                    partialJtByDiff[i] += partialJacobian[i][k] * partialDiff[k];

                        }
                    // wrong! fix it
                    /*                     
                                         synchronized(this){
                                            for (int i=0;i<numPars;i++) if (partialJacobian[i]!=null){
                                               JtByDiff[i]+=partialJtByDiff[i];
                                               for (int j=i;j<numPars;j++) JtByJmod[i][j]+=partialJtByJmod[i][j];
                                            }
                                         }
                     */
                    synchronizedCombinePartialJacobians(JtByJmod, //Transposed Jacobian multiplied by Jacobian
                            JtByDiff, partialJacobian, partialJtByDiff, partialJtByJmod, numPars);

                    final int numFinished = imageFinishedAtomic.getAndIncrement();
                    //                     IJ.showProgress(progressValues[numFinished]);
                    SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
                            // Here, we can safely update the GUI
                            // because we'll be called from the
                            // event dispatch thread
                            IJ.showProgress(progressValues[numFinished]);
                        }
                    });
                    if (stopRequested.get() == 1) { // ASAP
                        interruptedAtomic.set(true);
                    }
                    //                     if (debugLevel>1) System.out.println("IJ.showProgress("+progressValues[numImage]+")");
                    //                     if (debugLevel>1) IJ.showStatus("Progress "+IJ.d2s(100*progressValues[numImage],2)+"%");
                }
            }
        };
    }
    startAndJoin(threads);
    if (interruptedAtomic.get()) {
        System.out.println("calculateJacobianArrays() aborted by user request");
        return null;
    }
    if (debugLevel > 3) {
        String msg = "calculateJacobianArrays() ALL_trace=";
        for (int ii = 0; ii < numPars; ii++)
            msg += IJ.d2s(JtByJmod[ii][ii], 5);
        System.out.println(msg);

    }

    for (int i = 0; i < numPars; i++) { // subtract lambda*diagonal , fill the symmetrical half below the diagonal
        for (int j = 0; j < i; j++)
            JtByJmod[i][j] = JtByJmod[j][i]; // it is symmetrical matrix, just copy
    }
    LMAArrays lMAArrays = new LMAArrays();
    lMAArrays.jTByJ = JtByJmod;
    lMAArrays.jTByDiff = JtByDiff;
    if (debugLevel > 3) {
        String msg = "calculateJacobianArrays() lMAArrays.jTByJ trace=";
        for (int ii = 0; ii < numPars; ii++)
            msg += IJ.d2s(lMAArrays.jTByJ[ii][ii], 5);
        System.out.println(msg);

    }
    return lMAArrays;
}

From source file:Distortions.java

public void allSensorsExtrapolationMapped(final int stationNumber, // has to be selected
        final double[][][] gridPCorr, final double shrinkBlurComboSigma, final double shrinkBlurComboLevel,
        final double alphaThreshold, final double step, final double interpolationSigma,
        final double tangentialRadius, final int scanDistance, final int resultDistance,
        final int interpolationDegree, final int threadsMax, final boolean updateStatus,
        final boolean showDebugImages, final int debugLevel) {
    if (updateStatus)
        IJ.showStatus("Extrapolating sensor corrections...");
    final AtomicInteger sensorNumberAtomic = new AtomicInteger(0);
    final AtomicInteger sensorFinishedAtomic = new AtomicInteger(0);
    final Thread[] threads = newThreadArray(threadsMax);
    final AtomicInteger stopRequested = this.stopRequested;
    final AtomicBoolean interruptedAtomic = new AtomicBoolean();
    final EyesisSubCameraParameters[] eyesisSubCameras = this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.eyesisSubCameras[stationNumber];
    final double[][] sensorMasks = this.fittingStrategy.distortionCalibrationData.sensorMasks;

    final int alphaIndex = 2;

    final int sensorWidth = fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorWidth;
    final int sensorHeight = fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorHeight;
    final int decimation = fittingStrategy.distortionCalibrationData.eyesisCameraParameters.decimateMasks;
    final int width = (sensorWidth - 1) / decimation + 1; // decimated width (648)
    final int height = (sensorHeight - 1) / decimation + 1; // decimated width (648)
    final boolean extraShowDebug = showDebugImages && (debugLevel > 2);

    for (int ithread = 0; ithread < threads.length; ithread++) {
        threads[ithread] = new Thread() {
            public void run() {
                DoubleGaussianBlur gb = null;
                double[][] debugMasks1 = null;
                double[][] debugMasks2 = null;
                String[] debugMaskTitles = { "original", "blured" };
                if (extraShowDebug) {
                    debugMasks1 = new double[2][];
                    debugMasks2 = new double[2][];
                }/* w w w  .j a va 2s .c  o  m*/
                if (shrinkBlurComboSigma > 0.0)
                    gb = new DoubleGaussianBlur();
                for (int sensorNum = sensorNumberAtomic.getAndIncrement(); (sensorNum < gridPCorr.length)
                        && !interruptedAtomic.get(); sensorNum = sensorNumberAtomic.getAndIncrement()) {
                    if (gridPCorr[sensorNum] != null) {
                        final double[] centerPXY = { eyesisSubCameras[sensorNum].px0,
                                eyesisSubCameras[sensorNum].py0 };
                        if (shrinkBlurComboSigma > 0.0) {
                            double sigma = shrinkBlurComboSigma / decimation;
                            int margin = (int) (2 * sigma);
                            int width1 = width + 2 * margin;
                            int height1 = height + 2 * margin;
                            if (extraShowDebug)
                                debugMasks2[0] = gridPCorr[sensorNum][alphaIndex].clone();
                            double[] mask = addMarginsThreshold(gridPCorr[sensorNum][alphaIndex], // double [] data,
                                    0.0, // double threshold,
                                    width, height, margin);
                            if (extraShowDebug)
                                debugMasks1[0] = mask.clone();
                            gb.blurDouble(mask, width1, height1, sigma, sigma, 0.01);

                            double k = 1.0 / (1.0 - shrinkBlurComboLevel);
                            for (int i = 0; i < mask.length; i++) {
                                mask[i] = k * (mask[i] - shrinkBlurComboLevel);
                                mask[i] = (mask[i] > 0.0) ? (mask[i] * mask[i]) : 0.0;
                            }
                            if (extraShowDebug)
                                debugMasks1[1] = mask.clone();
                            gridPCorr[sensorNum][alphaIndex] = removeMargins(mask, //double [] data,
                                    width, // w/o margins
                                    height, margin); //mask; // replace with 0.0 .. 1.0 mask
                            if (extraShowDebug)
                                debugMasks2[1] = gridPCorr[sensorNum][alphaIndex].clone();
                            if (extraShowDebug) {
                                (new showDoubleFloatArrays()).showArrays(debugMasks1, width1, height1, true,
                                        "M1-" + sensorNum, debugMaskTitles);
                                (new showDoubleFloatArrays()).showArrays(debugMasks2, width, height, true,
                                        "M2-" + sensorNum, debugMaskTitles);
                            }

                        }
                        singleSensorExtrapolationMapped(sensorNum, gridPCorr[sensorNum], sensorMasks[sensorNum],
                                width, decimation, alphaThreshold, step, centerPXY, interpolationSigma,
                                tangentialRadius, scanDistance, resultDistance, interpolationDegree,
                                (shrinkBlurComboSigma > 0.0), showDebugImages, debugLevel);
                        final int numFinished = sensorFinishedAtomic.getAndIncrement();
                        SwingUtilities.invokeLater(new Runnable() {
                            public void run() {
                                if (updateStatus)
                                    IJ.showProgress(numFinished, gridPCorr.length);
                            }
                        });
                        if (stopRequested.get() == 1) { // ASAP
                            interruptedAtomic.set(true);
                        }
                    } //if (selectedImages[numImage]){
                } // for (int numImage=imageNumberAtomic.getAndIncrement(); ...
            } // public void run() {
        };
    }
    startAndJoin(threads);
    if (updateStatus)
        IJ.showProgress(0);
    return;
}

From source file:com.microsoft.tfs.core.clients.versioncontrol.internal.localworkspace.LocalDataAccessLayer.java

/**
 *
 *
 *
 * @param workspace/*  w ww.  ja  v  a2s  .  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:com.microsoft.tfs.core.clients.versioncontrol.internal.localworkspace.LocalDataAccessLayer.java

public static GetOperation[] undoPendingChanges(final Workspace workspace, final LocalWorkspaceProperties wp,
        final WorkspaceVersionTable lv, final LocalPendingChangesTable pc,
        final Iterable<LocalPendingChange> pendingChanges, final ChangeType selectiveUndo,
        final AtomicReference<Failure[]> failures, final AtomicBoolean onlineOperationRequired) {
    // Our collection of GetOperations that we will return. There will be
    // one GetOperation for every undone pending change and for every item
    // affected by an undone recursive pending change. The dictionary is
    // keyed by (SourceServerItem, IsCommitted) just like the local version
    // table./*from  w w  w.  ja  v a  2 s .  c  o  m*/
    final Map<ServerItemIsCommittedTuple, GetOperation> getOps = new HashMap<ServerItemIsCommittedTuple, GetOperation>();

    // The UndoneChange structure encapsulates a pending change and its
    // destination server item in pending space (RevertToServerItem).
    final List<UndoneChange> undoneChanges = new ArrayList<UndoneChange>();

    // A hash table where we can check quickly to see if a server path has a
    // pending change being undone (by target server item)
    final Map<String, UndoneChange> undoneChangesMap = new HashMap<String, UndoneChange>();

    // When a recursive pending change is undone, there may be affected
    // child pending changes that are not undone. We store in this queue a
    // list of updates that need to be processed (atomically!).
    final List<RenamedPendingChange> renamedPendingChanges = new ArrayList<RenamedPendingChange>();

    // When undoing a rename, we need to make sure that the current target
    // server item isn't at or below a workspace mapping.
    List<String> workingFolderServerItems = null;

    // Failures generated by undo
    final List<Failure> failureList = new ArrayList<Failure>();

    int undoRenameCount = 0;

    // The RevertToServerItem starts out with the CommittedServerItem of the
    // pending change.
    for (final LocalPendingChange pcEntry : pendingChanges) {
        final ChangeType changeType = pcEntry.getChangeType().retain(selectiveUndo);
        final UndoneChange undoneChange = new UndoneChange(pcEntry, pcEntry.getServerItem(), changeType);

        // Add this item to our data structures
        undoneChanges.add(undoneChange);
        undoneChangesMap.put(undoneChange.getPendingChange().getTargetServerItem(), undoneChange);

        // We can't undo a checkin lock without going to the server. If we
        // match one, the entire undo operation needs to go to the server.
        if (undoneChange.isUndoingLock()
                || (undoneChange.isUndoingRename() && undoneChange.getPendingChange().isLock())) {
            return sendToServer(failures, onlineOperationRequired);
        }

        // Count how many renames we are undoing and make sure the rename is
        // not at or under a workspace mapping
        if (undoneChange.isUndoingRename()) {
            undoRenameCount++;

            // The first rename will initialize our list of working folders
            // and sort it
            if (null == workingFolderServerItems) {
                final WorkingFolder[] workingFolders = wp.getWorkingFolders();
                workingFolderServerItems = new ArrayList<String>(workingFolders.length);

                for (final WorkingFolder workingFolder : workingFolders) {
                    workingFolderServerItems.add(workingFolder.getServerItem());
                }

                Collections.sort(workingFolderServerItems, new Comparator<String>() {
                    @Override
                    public int compare(final String x, final String y) {
                        return ServerPath.compareTopDown(x, y);
                    }
                });
            }

            // Check to see if undoing this rename would modify the
            // workspace mappings
            final int index = Collections.binarySearch(workingFolderServerItems, pcEntry.getTargetServerItem(),
                    ServerPath.TOP_DOWN_COMPARATOR);

            if (index >= 0 || (~index < workingFolderServerItems.size() && ServerPath
                    .isChild(pcEntry.getTargetServerItem(), workingFolderServerItems.get(~index)))) {
                return sendToServer(failures, onlineOperationRequired);
            }
        }
    }

    // Sort by target server item descending
    Collections.sort(undoneChanges, new Comparator<UndoneChange>() {
        @Override
        public int compare(final UndoneChange x, final UndoneChange y) {
            return ServerPath.compareTopDown(y.getPendingChange().getTargetServerItem(),
                    x.getPendingChange().getTargetServerItem());
        }
    });

    // Pass 1: Calculate the RevertToServerItem for each undone pending
    // change.
    if (undoRenameCount > 0) {
        // We should come up with a faster way of figuring out whether the
        // user is undoing all renames in the workspace.
        int totalRenameCount = 0;
        final List<LocalPendingChange> remainingFolderRenames = new ArrayList<LocalPendingChange>();

        for (final LocalPendingChange pcEntry : pc.queryByTargetServerItem(ServerPath.ROOT, RecursionType.FULL,
                null)) {
            if (pcEntry.isRename()) {
                totalRenameCount++;

                if (pcEntry.isRecursiveChange()) {
                    final UndoneChange undoneChange = undoneChangesMap.get(pcEntry.getTargetServerItem());

                    if (undoneChange == null || !undoneChange.isUndoingRename()) {
                        remainingFolderRenames.add(pcEntry);
                    }
                }
            }
        }

        if (undoneChanges.size() != pc.getCount()) {
            // We are not undoing all the changes in the workspace, so we
            // need to make sure that we do not have any pending changes
            // that are not being undone that have a target server item that
            // is at or underneath the source of a pending rename. Otherwise
            // there will be a collision when we undo the rename and it goes
            // back to the source.

            for (final UndoneChange undoneChange : undoneChanges) {
                final LocalPendingChange lpc = undoneChange.getPendingChange();

                // TODO: What kinds of bad situations can we end up with
                // when you have a merge of a deleted item under a rename --
                // a pending merge on a deleted item
                if (0 == lpc.getDeletionID() && lpc.isCommitted() && undoneChange.isUndoingRename()
                        && !ServerPath.equals(lpc.getCommittedServerItem(), lpc.getTargetServerItem())) {
                    // Check to see if there is a namespace-additive pending
                    // change blocking this item from reverting to its
                    // committed server item
                    for (final LocalPendingChange pcEntry : pc.queryByTargetServerItem(
                            undoneChange.getPendingChange().getCommittedServerItem(), RecursionType.FULL,
                            null)) {
                        if (pcEntry.isAdd() || pcEntry.isBranch() || pcEntry.isRename()) {
                            final UndoneChange collision = undoneChangesMap.get(pcEntry.getTargetServerItem());

                            if (collision == null || !collision.getUndoneChangeType()
                                    .containsAny(ChangeType.ADD_BRANCH_OR_RENAME)) {
                                final String format = Messages
                                        .getString("LocalDataAccessLayer.PartialRenameConflictExceptionFormat"); //$NON-NLS-1$
                                throw new PartialRenameConflictException(
                                        MessageFormat.format(format, pcEntry.getTargetServerItem()));
                            }
                        }
                    }
                }
            }
        }

        if (undoRenameCount != totalRenameCount) {
            // Only some of the renames in the workspace are being undone

            // Find a pending folder rename (PARENT\a->PARENT\b) that is
            // NOT being undone which is affecting a pending folder rename
            // (PARENT\A\SUB -> OUTSIDE) that IS being undone Where the
            // depth of the target name for the rename being undone
            // (OUTSIDE) is less than the depth of the target name that is
            // NOT being undone (PARENT\B).
            for (final LocalPendingChange remainingFolderRename : remainingFolderRenames) {
                for (final LocalPendingChange pcEntry : pc.queryByCommittedServerItem(
                        remainingFolderRename.getCommittedServerItem(), RecursionType.FULL, null)) {
                    if (pcEntry.isRename() && pcEntry.isRecursiveChange()) {
                        final UndoneChange undoneChange = undoneChangesMap.get(pcEntry.getTargetServerItem());
                        final int targetFolderDepth = ServerPath.getFolderDepth(pcEntry.getTargetServerItem());
                        final int remainFolderDepth = ServerPath
                                .getFolderDepth(remainingFolderRename.getTargetServerItem());

                        if (undoneChange != null && undoneChange.isUndoingRename()
                                && targetFolderDepth < remainFolderDepth) {
                            final String format = Messages
                                    .getString("LocalDataAccessLayer.PartialRenameConflictExceptionFormat"); //$NON-NLS-1$
                            throw new PartialRenameConflictException(
                                    MessageFormat.format(format, pcEntry.getCommittedServerItem()));
                        }
                    }
                }
            }

            // Calculate new names for all namespace-changing pending
            // changes.

            // Map of key server item (current target server item) to the
            // data structure used for the name calculation. We'll use this
            // later to sub in the new names.
            final Map<String, RenameCalculationEntry> newNames = new HashMap<String, RenameCalculationEntry>();

            // Our algorithm wants to walk the set of pending renames only.
            final List<RenameCalculationEntry> pendingRenamesOnly = new ArrayList<RenameCalculationEntry>(
                    totalRenameCount);

            for (final UndoneChange undoneChange : undoneChanges) {
                final RenameCalculationEntry rcEntry = new RenameCalculationEntry(
                        undoneChange.getPendingChange().getTargetServerItem(),
                        undoneChange.getPendingChange().getServerItem(), undoneChange.getPendingChange(),
                        undoneChange.isUndoingRename());

                newNames.put(undoneChange.getPendingChange().getTargetServerItem(), rcEntry);

                if (undoneChange.getPendingChange().isRename()) {
                    pendingRenamesOnly.add(rcEntry);
                }
            }

            for (final LocalPendingChange pcEntry : pc.queryByTargetServerItem(ServerPath.ROOT,
                    RecursionType.FULL, null)) {
                if ((pcEntry.isRename() || pcEntry.isAdd() || pcEntry.isBranch())
                        && !undoneChangesMap.containsKey(pcEntry.getTargetServerItem())) {
                    final RenameCalculationEntry rcEntry = new RenameCalculationEntry(
                            pcEntry.getTargetServerItem(), pcEntry.getServerItem(), pcEntry, false);

                    newNames.put(pcEntry.getTargetServerItem(), rcEntry);

                    if (pcEntry.isRename()) {
                        pendingRenamesOnly.add(rcEntry);
                    }
                }
            }

            // Our algorithm wants to walk the set of pending renames only,
            // by source server item ascending.
            Collections.sort(pendingRenamesOnly, new Comparator<RenameCalculationEntry>() {
                @Override
                public int compare(final RenameCalculationEntry x, final RenameCalculationEntry y) {
                    return ServerPath.compareTopDown(x.getPendingChange().getCommittedServerItem(),
                            y.getPendingChange().getCommittedServerItem());
                }
            });

            for (final RenameCalculationEntry newName : pendingRenamesOnly) {
                // Capture the data from newName into local variables, since
                // we will be checking/editing values on the very same
                // instance of RenameCalculationEntry in our up coming
                // for each loops
                final String sourceServerItem = newName.getSourceServerItem();
                final String targetServerItem = newName.getTargetServerItem();

                if (!newName.isUndoingChange()) {
                    for (final RenameCalculationEntry rcEntry : newNames.values()) {
                        final String entrySourceServerItem = rcEntry.getSourceServerItem();
                        if (ServerPath.isChild(sourceServerItem, entrySourceServerItem)) {
                            final String entryTargetServerItem = rcEntry.getTargetServerItem();
                            final String pendingTargetServerItem = rcEntry.getPendingChange()
                                    .getTargetServerItem();

                            if (!ServerPath.equals(entrySourceServerItem, entryTargetServerItem)
                                    || ServerPath.equals(pendingTargetServerItem, entrySourceServerItem)) {
                                rcEntry.setSourceServerItem(targetServerItem
                                        + entrySourceServerItem.substring(sourceServerItem.length()));
                            }
                        }
                    }
                } else {
                    for (final RenameCalculationEntry rcEntry : newNames.values()) {
                        final String entryTargetServerItem = rcEntry.getTargetServerItem();
                        if (ServerPath.isChild(targetServerItem, entryTargetServerItem)) {
                            final String entrySourceServerItem = rcEntry.getSourceServerItem();
                            final String pendingTargetServerItem = rcEntry.getPendingChange()
                                    .getTargetServerItem();

                            if (!ServerPath.equals(entrySourceServerItem, entryTargetServerItem)
                                    || ServerPath.equals(pendingTargetServerItem, entrySourceServerItem)) {
                                rcEntry.setTargetServerItem(sourceServerItem
                                        + entryTargetServerItem.substring(targetServerItem.length()));
                            }
                        }
                    }
                }
            }

            // If there are duplicate TargetServerItem values in the set of
            // RenameCalculationEntry objects, that indicates we have a
            // collision and cannot perform the undo. Sort by target server
            // item so that duplicates will be adjacent.
            final RenameCalculationEntry[] rcEntries = newNames.values()
                    .toArray(new RenameCalculationEntry[newNames.size()]);

            Arrays.sort(rcEntries, new Comparator<RenameCalculationEntry>() {
                @Override
                public int compare(final RenameCalculationEntry x, final RenameCalculationEntry y) {
                    return ServerPath.compareTopDown(x.getTargetServerItem(), y.getTargetServerItem());
                }
            });

            // The loop is complicated because we need to exclude pending
            // renames on deleted items from consideration.
            int duplicateCheckIndex = -1;

            for (int i = 1; i < rcEntries.length; i++) {
                // Only allow rcEntries[duplicateCheckIndex] to point to a
                // pending change which meets our criteria
                if (rcEntries[i - 1].getPendingChange().getDeletionID() == 0
                        || !rcEntries[i - 1].getPendingChange().isRename()) {
                    duplicateCheckIndex = i - 1;
                }

                // This pending change must also meet the criteria, we must
                // have something to compare it against, and the target
                // server items need to be the same.
                if (duplicateCheckIndex >= 0
                        && (rcEntries[i].getPendingChange().getDeletionID() == 0
                                || !rcEntries[i].getPendingChange().isRename())
                        && ServerPath.equals(rcEntries[i].getTargetServerItem(),
                                rcEntries[duplicateCheckIndex].getTargetServerItem())) {
                    throw new PartialRenameConflictException(MessageFormat.format(
                            Messages.getString("LocalDataAccessLayer.PartialRenameConflictExceptionFormat"), //$NON-NLS-1$ ,
                            rcEntries[i].getTargetServerItem()));
                }
            }

            for (final UndoneChange undoneChange : undoneChanges) {
                final RenameCalculationEntry rcEntry = newNames
                        .get(undoneChange.getPendingChange().getTargetServerItem());

                if (rcEntry != null) {
                    undoneChange.setRevertToServerItem(rcEntry.getTargetServerItem());
                }
            }
        } else {
            // All renames in the workspace are being undone.
            for (final UndoneChange undoneChange : undoneChanges) {
                if (undoneChange.getPendingChange().isCommitted()) {
                    // Committed changes have their revert to server item
                    // already calculated.
                    undoneChange
                            .setRevertToServerItem(undoneChange.getPendingChange().getCommittedServerItem());
                } else {
                    // Find the closest rename that affects this uncommitted
                    // item and unrename it.
                    undoneChange.setRevertToServerItem(pc.getCommittedServerItemForTargetServerItem(
                            undoneChange.getPendingChange().getTargetServerItem()));
                }
            }
        }
    } else {
        // Even though we are not undoing a rename, there could be a
        // parental rename. So set the revert to server item based upon
        // existing parental renames.
        for (final UndoneChange undoneChange : undoneChanges) {
            undoneChange.setRevertToServerItem(undoneChange.getPendingChange().getTargetServerItem());
        }
    }

    // Pass 1: One GetOperation for every LocalPendingChange being undone
    for (final UndoneChange undoneChange : undoneChanges) {
        if (undoneChange.getRevertToServerItem().length() > VersionControlConstants.MAX_SERVER_PATH_SIZE) {
            throw createPathTooLongException(undoneChange.getRevertToServerItem());
        }

        final LocalPendingChange pcEntry = undoneChange.getPendingChange();
        final WorkspaceLocalItem lvEntry = lv.getByPendingChange(undoneChange.getPendingChange());

        final GetOperation getOp = new GetOperation();

        getOp.setTargetServerItem(undoneChange.getRevertToServerItem());
        getOp.setSourceServerItem(
                pcEntry.isCommitted() ? pcEntry.getCommittedServerItem() : pcEntry.getTargetServerItem());

        if (null != lvEntry && !lvEntry.isDeleted()) {
            getOp.setSourceLocalItem(lvEntry.getLocalItem());

            // If we're undoing a pending add, mark the path as changed in
            // the scanner. This is because when the pending change is
            // undone, the item in question will not actually be touched on
            // disk. But we want to have it marked, so that we re-detect the
            // item as a candidate add.
            if (undoneChange.isUndoingAdd()) {
                workspace.getWorkspaceWatcher().markPathChanged(lvEntry.getLocalItem());
                LocalWorkspaceTransaction.getCurrent().setRaisePendingChangeCandidatesChanged(true);
            }
        }

        if ((0 == pcEntry.getDeletionID()
                || undoneChange.getRemainingChangeType().contains(ChangeType.UNDELETE))
                && !undoneChange.isUndoingBranch()) {
            final String targetLocalItem = WorkingFolder
                    .getLocalItemForServerItem(undoneChange.getRevertToServerItem(), wp.getWorkingFolders());

            if (null != lvEntry) {
                getOp.setTargetLocalItem(targetLocalItem);

                // We never want the client to delete adds -- even if the
                // target is cloaked.
                if (pcEntry.isAdd() && null == getOp.getTargetLocalItem()) {
                    getOp.setTargetLocalItem(getOp.getSourceLocalItem());
                }
            } else {
                // We don't have a local version entry for this pending
                // change, so we can't restore the content.
                getOp.setTargetLocalItem(null);

                if (null != targetLocalItem) {
                    final String format = "OfflineUndoNoLocalVersionEntry"; //$NON-NLS-1$
                    failureList
                            .add(new Failure(MessageFormat.format(format, undoneChange.getRevertToServerItem()),
                                    FailureCodes.BASELINE_UNAVAILABLE_EXCEPTION, SeverityType.WARNING,
                                    undoneChange.getRevertToServerItem()));
                }
            }

            if (null != getOp.getTargetLocalItem()) {
                getOp.setLocalVersionEntry(lv.getByLocalItem(getOp.getTargetLocalItem()));
            }
        }

        // This is the current encoding on the pending change -- we need the
        // committed encoding, which is on the local version entry if we
        // have one, but if we don't, we're in trouble and need to go to the
        // server.
        if (!pcEntry.getChangeType().contains(ChangeType.ENCODING)) {
            // If we aren't changing the encoding, then the local pending
            // change row's encoding is the encoding for the item.

            getOp.setEncoding(pcEntry.getEncoding());
        } else if (null != lvEntry) {
            getOp.setEncoding(lvEntry.getEncoding());
        } else {
            // We don't have the committed encoding for this item stored
            // locally. We need to process this undo operation on the
            // server.

            // TODO: Issue a warning and not download the change? The user
            // can go to the server and get it later, we don't want to
            // completely block them while they're offline
            return sendToServer(failures, onlineOperationRequired);
        }

        getOp.setChangeType(undoneChange.getUndoneChangeType());

        // If we are undoing an uncommitted pending change then do not add
        // in parent recursive changetypes
        if (!undoneChange.isUndoingAdd() && !undoneChange.isUndoingBranch()) {
            ChangeType inheritedChangeType = ChangeType.NONE;

            // The ChangeType on the item being undone is equal to the
            // ChangeType on the item itself, plus the recursive ChangeType
            // on its parent pending changes which are also being undone.
            for (final LocalPendingChange parentPcEntry : pc
                    .queryParentsOfTargetServerItem(pcEntry.getTargetServerItem())) {
                final UndoneChange checkChange = undoneChangesMap.get(parentPcEntry.getTargetServerItem());

                if (!parentPcEntry.isRecursiveChange() || checkChange == null) {
                    continue;
                }

                if (checkChange.getUndoneChangeType().contains(ChangeType.RENAME)) {
                    inheritedChangeType = inheritedChangeType.combine(ChangeType.RENAME);
                }
                if (checkChange.getUndoneChangeType().contains(ChangeType.DELETE)) {
                    inheritedChangeType = inheritedChangeType.combine(ChangeType.DELETE);
                }
            }

            getOp.setChangeType(inheritedChangeType.combine(getOp.getChangeType()));
        }

        getOp.setDeletionID(pcEntry.getDeletionID());
        getOp.setItemType(pcEntry.getItemType());
        getOp.setPendingChangeID(LocalPendingChange.LOCAL_PENDING_CHANGE_ID);
        getOp.setItemID(pcEntry.getItemID());

        if (null != lvEntry) {
            if (lvEntry.isCommitted() && !lvEntry.isDirectory()) {
                getOp.setBaselineFileGUID(
                        lvEntry.hasBaselineFileGUID() ? lvEntry.getBaselineFileGUID() : new byte[16]);
            }

            getOp.setHashValue(lvEntry.getHashValue());
            getOp.setVersionLocal(lvEntry.isDeleted() ? 0 : lvEntry.getVersion());
            getOp.setVersionServer(lvEntry.getVersion());
            getOp.setVersionServerDate((-1 == lvEntry.getCheckinDate()) ? DotNETDate.MIN_CALENDAR
                    : DotNETDate.fromWindowsFileTimeUTC(lvEntry.getCheckinDate()));
            getOp.setPropertyValues(pcEntry.getPropertyValues());
        } else {
            getOp.setVersionServer(pcEntry.getVersion());
        }

        getOps.put(new ServerItemIsCommittedTuple(getOp.getSourceServerItem(), pcEntry.isCommitted()), getOp);

        // Remove local version rows for adds, branches where the item is an
        // add, or we are syncing an item on top of an undone branch.
        if (undoneChange.isUndoingAdd()
                || (undoneChange.isUndoingBranch() && getOp.getTargetLocalItem() != null)) {
            if (null != lvEntry) {
                lv.removeByServerItem(lvEntry.getServerItem(), lvEntry.isCommitted(), true);
            }
        }
    }

    // Pass 2: Affected items underneath undone recursive changes
    for (final UndoneChange undoneChange : undoneChanges) {
        if (!undoneChange.isUndoingRecursiveChange()) {
            continue;
        }

        // The sort order means that undoneChange is always the closest
        // recursive operation affecting the item
        for (final WorkspaceLocalItem lvEntry : ParsedItemSpec.queryLocalVersionsByTargetServerItem(lv, pc,
                undoneChange.getPendingChange().getTargetServerItem(), RecursionType.FULL, null,
                ParsedItemSpecOptions.INCLUDE_DELETED)) {
            if (getOps.containsKey(
                    new ServerItemIsCommittedTuple(lvEntry.getServerItem(), lvEntry.isCommitted()))) {
                continue;
            }

            final String currentServerItem = lvEntry.isCommitted()
                    ? pc.getTargetServerItemForCommittedServerItem(lvEntry.getServerItem())
                    : lvEntry.getServerItem();

            final GetOperation getOp = new GetOperation();

            getOp.setSourceLocalItem(lvEntry.isDeleted() ? null : lvEntry.getLocalItem());

            getOp.setTargetServerItem(undoneChange.getRevertToServerItem() + currentServerItem
                    .substring(undoneChange.getPendingChange().getTargetServerItem().length()));

            if (getOp.getTargetServerItem().length() > VersionControlConstants.MAX_SERVER_PATH_SIZE) {
                throw createPathTooLongException(getOp.getTargetServerItem());
            }

            getOp.setSourceServerItem(
                    lvEntry.isCommitted() ? lvEntry.getServerItem() : getOp.getTargetServerItem());

            getOp.setTargetLocalItem(WorkingFolder.getLocalItemForServerItem(getOp.getTargetServerItem(),
                    wp.getWorkingFolders()));

            if (null != getOp.getTargetLocalItem()) {
                getOp.setLocalVersionEntry(lv.getByLocalItem(getOp.getTargetLocalItem()));
            }

            getOp.setDeletionID(0);
            getOp.setEncoding(lvEntry.getEncoding());
            getOp.setItemType(lvEntry.isDirectory() ? ItemType.FOLDER : ItemType.FILE);
            getOp.setPropertyValues(lvEntry.getPropertyValues());

            // Even if this item has a pending change which is not being
            // undone -- we return 0 here
            getOp.setPendingChangeID(0);
            getOp.setItemID(lvEntry.getItemID());

            if (!ServerPath.equals(currentServerItem, getOp.getTargetServerItem())) {
                if (!lvEntry.isCommitted()
                        && !ServerPath.equals(currentServerItem, getOp.getTargetServerItem())) {
                    // Uncommitted items have the itemid of the target
                    // server item, and we're changing paths, so set the
                    // item id to 0 because we have no idea what the item id
                    // of the target server item is
                    getOp.setItemID(0);
                }

                final LocalPendingChange pcEntry = pc.getByTargetServerItem(currentServerItem);

                if (null != pcEntry) {
                    if (pcEntry.isLock()) {
                        // We cannot change the path of an item with a
                        // pending lock locally.
                        return sendToServer(failures, onlineOperationRequired);
                    }

                    if (pcEntry.hasMergeConflict()) {
                        throw new CannotRenameDueToChildConflictException(
                                undoneChange.getPendingChange().getTargetServerItem(),
                                pcEntry.getTargetServerItem());
                    }

                    // Queue this pending change for a later update of its
                    // target path and itemid (if it still exists after
                    // removing those pending changes that are being undone)
                    renamedPendingChanges
                            .add(new RenamedPendingChange(currentServerItem, getOp.getTargetServerItem()));
                }
            }

            if (lvEntry.isCommitted() && !lvEntry.isDirectory()) {
                getOp.setBaselineFileGUID(
                        lvEntry.hasBaselineFileGUID() ? lvEntry.getBaselineFileGUID() : new byte[16]);
            }

            getOp.setHashValue(lvEntry.getHashValue());
            getOp.setVersionLocal(lvEntry.isDeleted() ? 0 : lvEntry.getVersion());
            getOp.setVersionServer(lvEntry.getVersion());
            getOp.setVersionServerDate((-1 == lvEntry.getCheckinDate()) ? DotNETDate.MIN_CALENDAR
                    : DotNETDate.fromWindowsFileTimeUTC(lvEntry.getCheckinDate()));
            getOp.setChangeType(ChangeType.NONE);

            // We'll take a quick look at the parents of this target server
            // item to determine if the item is still deleted. On this same
            // pass, we'll compute the ChangeType of the GetOperation to
            // generate. Since there was no pending change being undone on
            // this item, the ChangeType is equal to the union of the
            // recursive changetype bits on parent pending changes which are
            // being undone.
            boolean stillDeleted = false;

            for (final LocalPendingChange parentPcEntry : pc
                    .queryParentsOfTargetServerItem(currentServerItem)) {
                final UndoneChange checkChange = undoneChangesMap.get(parentPcEntry.getTargetServerItem());

                if (checkChange == null) {
                    if (parentPcEntry.isDelete()) {
                        stillDeleted = true;

                        // Who cares what the ChangeType on the GetOperation
                        // is, if we're not going to emit it?
                        break;
                    }
                } else {
                    ChangeType changeType = getOp.getChangeType();
                    changeType = changeType.combine(checkChange.getUndoneChangeType());
                    changeType = changeType.combine(ChangeType.RENAME_OR_DELETE);
                    getOp.setChangeType(changeType);
                }
            }

            if (!lvEntry.isDeleted() || !stillDeleted) {
                if (null != getOp.getTargetLocalItem() || null != getOp.getSourceLocalItem()) {
                    getOps.put(new ServerItemIsCommittedTuple(lvEntry.getServerItem(), lvEntry.isCommitted()),
                            getOp);
                }
            }
        }
    }

    // Remove the pending change rows, putting back modified changes for
    // those entries which were selective undoes. Do this in two loops so
    // the changes are atomic.
    final List<LocalPendingChange> selectiveUndoChanges = new ArrayList<LocalPendingChange>();

    for (final UndoneChange undoneChange : undoneChanges) {
        pc.remove(undoneChange.getPendingChange());

        // If this was a selective undo, add an entry to the table
        if (!undoneChange.getUndoneChangeType().equals(undoneChange.getPendingChange().getChangeType())) {
            final LocalPendingChange newChange = undoneChange.getPendingChange().clone();
            newChange.setChangeType(
                    undoneChange.getPendingChange().getChangeType().remove(undoneChange.getUndoneChangeType()));
            newChange.setTargetServerItem(undoneChange.getRevertToServerItem());

            selectiveUndoChanges.add(newChange);
        }
    }

    // Second loop -- pend the selective undo changes.
    for (final LocalPendingChange pcEntry : selectiveUndoChanges) {
        pc.pendChange(pcEntry);
    }

    // Update the pending changes that were not undone but were affected by
    // parental renames.
    // Do this in two loops (remove+capture, modify+apply) so the changes
    // are atomic.
    for (final RenamedPendingChange renamedPendingChange : renamedPendingChanges) {
        final LocalPendingChange pcEntry = pc
                .getByTargetServerItem(renamedPendingChange.getOldTargetServerItem());

        if (null != pcEntry) {
            pc.remove(pcEntry);
            renamedPendingChange.setPendingChange(pcEntry);

            if (!pcEntry.isCommitted()) {
                final WorkspaceLocalItem lvEntry = lv
                        .getByServerItem(renamedPendingChange.getOldTargetServerItem(), false);

                if (null != lvEntry) {
                    renamedPendingChange.setLocalVersion(lvEntry);
                    lv.removeByServerItem(lvEntry.getServerItem(), lvEntry.isCommitted(), true);
                }
            }
        }
    }

    // Second loop -- apply the data to the tables after modifying it
    for (final RenamedPendingChange renamedPendingChange : renamedPendingChanges) {
        final LocalPendingChange pcEntry = renamedPendingChange.getPendingChange();
        final WorkspaceLocalItem lvEntry = renamedPendingChange.getLocalVersion();

        if (null != pcEntry) {
            pcEntry.setTargetServerItem(renamedPendingChange.getTargetServerItem());

            if (!pcEntry.isCommitted()) {
                pcEntry.setItemID(0);
            }

            pc.pendChange(pcEntry);
        }

        if (null != lvEntry) {
            lvEntry.setServerItem(renamedPendingChange.getTargetServerItem());
            lvEntry.setItemID(0);
            lv.add(lvEntry);
        }
    }

    failures.set(failureList.toArray(new Failure[failureList.size()]));
    onlineOperationRequired.set(false);

    return getOps.values().toArray(new GetOperation[getOps.size()]);
}