Example usage for java.util TreeSet addAll

List of usage examples for java.util TreeSet addAll

Introduction

In this page you can find the example usage for java.util TreeSet addAll.

Prototype

public boolean addAll(Collection<? extends E> c) 

Source Link

Document

Adds all of the elements in the specified collection to this set.

Usage

From source file:com.houghtonassociates.bamboo.plugins.dao.GerritService.java

public GerritChangeVO getLastChange(String project, String branch) throws RepositoryException {
    log.debug(String.format("getLastChange(project=%s)...", project));

    Set<GerritChangeVO> changes = getGerritChangeInfo(project, branch);

    TreeSet<GerritChangeVO> treeSet = new TreeSet<GerritChangeVO>(new SortByLastUpdate());
    treeSet.addAll(changes);

    if (treeSet.size() > 0)
        return treeSet.first();

    return null;/*ww  w. java2s.c o m*/
}

From source file:com.houghtonassociates.bamboo.plugins.dao.GerritService.java

public GerritChangeVO getLastUnverifiedChange() throws RepositoryException {
    log.debug("getLastUnverifiedChange()...");

    Set<GerritChangeVO> changes = getGerritChangeInfo();

    TreeSet<GerritChangeVO> treeSet = new TreeSet<GerritChangeVO>(new SortByUnVerifiedLastUpdate());
    treeSet.addAll(changes);

    if ((treeSet.size() > 0) && (treeSet.first().getVerificationScore() == 0))
        return treeSet.first();

    return null;//from  ww w.  j  a v a2  s .  c om
}

From source file:com.houghtonassociates.bamboo.plugins.dao.GerritService.java

public GerritChangeVO getLastUnverifiedChange(String project) throws RepositoryException {
    log.debug(String.format("getLastUnverifiedChange(project=%s)...", project));

    Set<GerritChangeVO> changes = getGerritChangeInfo(project);

    TreeSet<GerritChangeVO> treeSet = new TreeSet<GerritChangeVO>(new SortByUnVerifiedLastUpdate());
    treeSet.addAll(changes);

    if ((treeSet.size() > 0) && (treeSet.first().getVerificationScore() == 0))
        return treeSet.first();

    return null;// w w w . j  ava 2 s. c om
}

From source file:com.houghtonassociates.bamboo.plugins.dao.GerritService.java

public GerritChangeVO getLastUnverifiedChange(String project, String branch) throws RepositoryException {
    log.debug(String.format("getLastUnverifiedChange(project=%s)...", project));

    Set<GerritChangeVO> changes = getGerritChangeInfo(project, branch);

    TreeSet<GerritChangeVO> treeSet = new TreeSet<GerritChangeVO>(new SortByUnVerifiedLastUpdate());
    treeSet.addAll(changes);

    if ((treeSet.size() > 0) && (treeSet.first().getVerificationScore() == 0))
        return treeSet.first();

    return null;/*from   w  w  w . j ava  2  s.co  m*/
}

From source file:com.kelveden.rastajax.representation.flat.FlatRepresentationBuilder.java

@Override
public Set<FlatResource> buildRepresentationFor(final ResourceClass resourceClass) {

    final TreeSet<FlatResource> result = new TreeSet<FlatResource>(RESOURCE_COMPARATOR);

    LOGGER.debug(StringUtils.repeat("-", UNDERLINE_LENGTH));
    LOGGER.debug("Building representation for resource with URI template {}...",
            resourceClass.getUriTemplate());
    LOGGER.debug(StringUtils.repeat("-", UNDERLINE_LENGTH));

    if (resourceClass.isRootResource()) {

        LOGGER.debug("This resource is a root resource.");
        LOGGER.debug("Analyzing methods...");

        final MultiValuedMap<String, ResourceClassMethod> resourceClassMethodsByPath = groupResourceClassMethodsByUriTemplate(
                resourceClass, " |-");

        final List<FlatResource> methodsAsResources = representResourceClassMethods(resourceClass,
                resourceClassMethodsByPath);
        result.addAll(methodsAsResources);

        LOGGER.debug(/*from w  w w  .ja v  a  2 s.  c  o  m*/
                "Finished analyzing methods: flattened methods to {} distinct resource(s) in representation.",
                methodsAsResources.size());

    } else {
        LOGGER.debug("This resource is NOT a root resource - skipping.");
    }

    return result;
}

From source file:org.apache.lens.cube.parse.StorageCandidate.java

/**
 * Gets FactPartitions for the given fact using the following logic
 *
 * 1. Find the max update interval that will be used for the query. Lets assume time
 * range is 15 Sep to 15 Dec and the fact has two storage with update periods as MONTHLY,DAILY,HOURLY.
 * In this case the data for [15 sep - 1 oct)U[1 Dec - 15 Dec) will be answered by DAILY partitions
 * and [1 oct - 1Dec) will be answered by MONTHLY partitions. The max interavl for this query will be MONTHLY.
 *
 * 2.Prune Storgaes that do not fall in the queries time range.
 * {@link org.apache.lens.cube.metadata.CubeMetastoreClient#isStorageTableCandidateForRange(String, Date, Date)}
 *
 * 3. Iterate over max interavl . In out case it will give two months Oct and Nov. Find partitions for
 * these two months.Check validity of FactPartitions for Oct and Nov
 * via {@link #updatePartitionStorage(FactPartition)}.
 * If the partition is missing, try getting partitions for the time range form other update periods (DAILY,HOURLY).
 * This is achieved by calling getPartitions() recursively but passing only 2 update periods (DAILY,HOURLY)
 *
 * 4.If the monthly partitions are found, check for lookahead partitions and call getPartitions recursively for the
 * remaining time intervals i.e, [15 sep - 1 oct) and [1 Dec - 15 Dec)
 *
 * TODO union : Move this into util.//from ww w  .  ja v a 2 s  .co m
 */
private boolean getPartitions(Date fromDate, Date toDate, String partCol, Set<FactPartition> partitions,
        TreeSet<UpdatePeriod> updatePeriods, boolean addNonExistingParts, boolean failOnPartialData,
        PartitionRangesForPartitionColumns missingPartitions) throws LensException {
    if (fromDate.equals(toDate) || fromDate.after(toDate)) {
        return true;
    }
    if (updatePeriods == null || updatePeriods.isEmpty()) {
        return false;
    }

    UpdatePeriod maxInterval = CubeFactTable.maxIntervalInRange(fromDate, toDate, updatePeriods);
    if (maxInterval == null) {
        log.info("No max interval for range: {} to {}", fromDate, toDate);
        return false;
    }

    if (maxInterval == UpdatePeriod.CONTINUOUS
            && cubeQueryContext.getRangeWriter().getClass().equals(BetweenTimeRangeWriter.class)) {
        FactPartition part = new FactPartition(partCol, fromDate, maxInterval, null, partWhereClauseFormat);
        partitions.add(part);
        part.getStorageTables().add(storageTable);
        part = new FactPartition(partCol, toDate, maxInterval, null, partWhereClauseFormat);
        partitions.add(part);
        part.getStorageTables().add(storageTable);
        this.participatingUpdatePeriods.add(maxInterval);
        log.info("Added continuous fact partition for storage table {}", storageName);
        return true;
    }

    if (!getCubeMetastoreClient().partColExists(this.getFact(), storageName, partCol)) {
        log.info("{} does not exist in {}", partCol, name);
        return false;
    }

    Date maxIntervalStorageTblStartDate = getStorageTableStartDate(maxInterval);
    Date maxIntervalStorageTblEndDate = getStorageTableEndDate(maxInterval);

    TreeSet<UpdatePeriod> remainingIntervals = new TreeSet<>(updatePeriods);
    remainingIntervals.remove(maxInterval);
    if (!isCandidatePartiallyValidForTimeRange(maxIntervalStorageTblStartDate, maxIntervalStorageTblEndDate,
            fromDate, toDate)) {
        //Check the time range in remainingIntervals as maxInterval is not useful
        return getPartitions(fromDate, toDate, partCol, partitions, remainingIntervals, addNonExistingParts,
                failOnPartialData, missingPartitions);
    }

    Date ceilFromDate = DateUtil.getCeilDate(
            fromDate.after(maxIntervalStorageTblStartDate) ? fromDate : maxIntervalStorageTblStartDate,
            maxInterval);
    Date floorToDate = DateUtil.getFloorDate(
            toDate.before(maxIntervalStorageTblEndDate) ? toDate : maxIntervalStorageTblEndDate, maxInterval);
    if (ceilFromDate.equals(floorToDate) || floorToDate.before(ceilFromDate)) {
        return getPartitions(fromDate, toDate, partCol, partitions, remainingIntervals, addNonExistingParts,
                failOnPartialData, missingPartitions);
    }

    int lookAheadNumParts = getConf().getInt(CubeQueryConfUtil.getLookAheadPTPartsKey(maxInterval),
            CubeQueryConfUtil.DEFAULT_LOOK_AHEAD_PT_PARTS);
    TimeRange.Iterable.Iterator iter = TimeRange.iterable(ceilFromDate, floorToDate, maxInterval, 1).iterator();
    // add partitions from ceilFrom to floorTo
    while (iter.hasNext()) {
        Date dt = iter.next();
        Date nextDt = iter.peekNext();
        FactPartition part = new FactPartition(partCol, dt, maxInterval, null, partWhereClauseFormat);
        updatePartitionStorage(part);
        log.debug("Storage tables containing Partition {} are: {}", part, part.getStorageTables());
        if (part.isFound()) {
            log.debug("Adding existing partition {}", part);
            partitions.add(part);
            this.participatingUpdatePeriods.add(maxInterval);
            log.debug("Looking for look ahead process time partitions for {}", part);
            if (processTimePartCol == null) {
                log.debug("processTimePartCol is null");
            } else if (partCol.equals(processTimePartCol)) {
                log.debug("part column is process time col");
            } else if (updatePeriods.first().equals(maxInterval)) {
                log.debug("Update period is the least update period");
            } else if ((iter.getNumIters() - iter.getCounter()) > lookAheadNumParts) {
                // see if this is the part of the last-n look ahead partitions
                log.debug("Not a look ahead partition");
            } else {
                log.debug("Looking for look ahead process time partitions for {}", part);
                // check if finer partitions are required
                // final partitions are required if no partitions from
                // look-ahead
                // process time are present
                TimeRange.Iterable.Iterator processTimeIter = TimeRange
                        .iterable(nextDt, lookAheadNumParts, maxInterval, 1).iterator();
                while (processTimeIter.hasNext()) {
                    Date pdt = processTimeIter.next();
                    Date nextPdt = processTimeIter.peekNext();
                    FactPartition processTimePartition = new FactPartition(processTimePartCol, pdt, maxInterval,
                            null, partWhereClauseFormat);
                    updatePartitionStorage(processTimePartition);
                    if (processTimePartition.isFound()) {
                        log.debug("Finer parts not required for look-ahead partition :{}", part);
                    } else {
                        log.debug("Looked ahead process time partition {} is not found", processTimePartition);
                        TreeSet<UpdatePeriod> newset = new TreeSet<UpdatePeriod>();
                        newset.addAll(updatePeriods);
                        newset.remove(maxInterval);
                        log.debug("newset of update periods:{}", newset);
                        if (!newset.isEmpty()) {
                            // Get partitions for look ahead process time
                            log.debug("Looking for process time partitions between {} and {}", pdt, nextPdt);
                            Set<FactPartition> processTimeParts = getPartitions(
                                    TimeRange.builder().fromDate(pdt).toDate(nextPdt)
                                            .partitionColumn(processTimePartCol).build(),
                                    newset, true, failOnPartialData, missingPartitions);
                            log.debug("Look ahead partitions: {}", processTimeParts);
                            TimeRange timeRange = TimeRange.builder().fromDate(dt).toDate(nextDt).build();
                            for (FactPartition pPart : processTimeParts) {
                                log.debug("Looking for finer partitions in pPart: {}", pPart);
                                for (Date date : timeRange.iterable(pPart.getPeriod(), 1)) {
                                    FactPartition innerPart = new FactPartition(partCol, date,
                                            pPart.getPeriod(), pPart, partWhereClauseFormat);
                                    updatePartitionStorage(innerPart);
                                    innerPart.setFound(pPart.isFound());
                                    if (innerPart.isFound()) {
                                        partitions.add(innerPart);
                                    }
                                }
                                log.debug("added all sub partitions blindly in pPart: {}", pPart);
                            }
                        }
                    }
                }
            }
        } else {
            log.info("Partition:{} does not exist in any storage table", part);
            if (!getPartitions(dt, nextDt, partCol, partitions, remainingIntervals, false, failOnPartialData,
                    missingPartitions)) {
                log.debug("Adding non existing partition {}", part);
                if (addNonExistingParts) {
                    // Add non existing partitions for all cases of whether we populate all non existing or not.
                    this.participatingUpdatePeriods.add(maxInterval);
                    missingPartitions.add(part);
                    if (!failOnPartialData) {
                        partitions.add(part);
                        part.getStorageTables().add(storageTable);
                    }
                } else {
                    log.info("No finer granualar partitions exist for {}", part);
                    return false;
                }
            } else {
                log.debug("Finer granualar partitions added for {}", part);
            }
        }
    }

    return getPartitions(fromDate, ceilFromDate, partCol, partitions, remainingIntervals, addNonExistingParts,
            failOnPartialData, missingPartitions)
            && getPartitions(floorToDate, toDate, partCol, partitions, remainingIntervals, addNonExistingParts,
                    failOnPartialData, missingPartitions);
}

From source file:org.gvsig.framework.web.service.impl.OGCInfoServiceImpl.java

/**
 * Recursive method to add list layers get by the WMSServer into tree list
 *
 * @param children Represents child layers of parentNode
 * @param tree Tree of layers/*from   www  . ja  v a  2 s .  c o  m*/
 * @param crs CRS that must have the layers to add these to the tree
 * @param parentNode Represents parent layer
 * @param layersMap Represents the map that contains the layers obtained
 * @param isCalledByWizard Indicate if the method is called by the wizard
 */
private void generateWMSChildrenNodes(ArrayList<WMSLayer> children, List<TreeNode> tree,
        TreeSet<String> listCrs, TreeNode parentNode,
        Map<String, org.gvsig.framework.web.ogc.WMSLayer> layersMap, WMSInfo wmsInfo) {
    for (WMSLayer layerChild : children) {
        // get crs (srs) (belong to layer)
        Vector crsVector = layerChild.getAllSrs();
        // Only get the layers with have crs parameter or if crs is null
        if (listCrs.isEmpty() || !Collections.disjoint(crsVector, listCrs)) {

            ArrayList<WMSLayer> layerChildChildren = layerChild.getChildren();
            TreeNode layerChildNode = new TreeNode(layerChild.getName());
            layerChildNode.setTitle(layerChild.getTitle());

            // Get the children and their information
            if (layerChildChildren.isEmpty()) {
                layerChildNode.setFolder(false);

                // Add layer to layer map
                org.gvsig.framework.web.ogc.WMSLayer wmsLayer = new org.gvsig.framework.web.ogc.WMSLayer();
                TreeSet<String> crsSet = new TreeSet<String>();
                crsSet.addAll(layerChild.getAllSrs());
                wmsLayer.setCrs(crsSet);
                List<WMSStyle> wmsStyles = createListWMSStyles(layerChild.getStyles());
                wmsLayer.setStyles(wmsStyles);
                wmsLayer.setTitle(layerChild.getTitle());
                wmsLayer.setName(layerChild.getName());
                layersMap.put(layerChild.getName(), wmsLayer);

                // add to wmsinfo the layers supported by this layer
                TreeSet<String> crsSupported = wmsInfo.getCrsSupported();
                crsSupported.addAll(layerChild.getAllSrs());
                wmsInfo.setCrsSupported(crsSupported);

                //create one child for each crs of the layer
                if (listCrs.isEmpty() || listCrs.size() > 1) {
                    for (String crs : crsSet) {
                        if (StringUtils.isNotEmpty(crs) && (listCrs.isEmpty() || listCrs.contains(crs))) {
                            TreeNode crsNode = new TreeNode(crs);
                            crsNode.setHideCheckbox(true);
                            crsNode.setUnselectable(true);
                            crsNode.setIconclass(" ");
                            layerChildNode.addChild(crsNode);
                        }
                    }
                }
            } else {
                layerChildNode.setFolder(true);
                layerChildNode.setExpanded(true);
                generateWMSChildrenNodes(layerChildChildren, tree, listCrs, layerChildNode, layersMap, wmsInfo);
            }
            parentNode.addChild(layerChildNode);
        }
    }

}

From source file:org.zaproxy.zap.extension.ascanrulesBeta.UsernameEnumeration.java

/**
 * looks for username enumeration in the login page, by changing the username field to be a
 * valid / invalid user, and looking for differences in the response
 *///from   w ww  .  j  a v a  2  s . c  o m
@Override
public void scan() {

    // the technique to determine if usernames can be enumerated is as follows, using a variant
    // of the Freiling+Schinzel method,
    // adapted to the case where we do not know which is the username field
    //
    // 1) Request the original URL n times. (The original URL is assumed to have a valid
    // username, if not a valid password). Store the results in A[].
    // 2) Compute the longest common subsequence (LCS) of A[] into LCS_A
    // 3) for each parameter in the original URL (ie, for URL params, form params, and cookie
    // params)
    //   4) Change the current parameter (which we assume is the username parameter) to an invalid
    // username (randomly), and request the URL n times. Store the results in B[].
    //   5) Compute the longest common subsequence (LCS) of B[] into LCS_B
    //   6) If LCS_A <> LCS_B, then there is a Username Enumeration issue on the current parameter

    try {
        boolean loginUrl = false;

        // Are we dealing with a login url in any of the contexts of which this uri is part
        URI requestUri = getBaseMsg().getRequestHeader().getURI();

        // using the session, get the list of contexts for the url
        List<Context> contextList = extAuth.getModel().getSession().getContextsForUrl(requestUri.getURI());

        // now loop, and see if the url is a login url in each of the contexts in turn...
        for (Context context : contextList) {
            URI loginUri = extAuth.getLoginRequestURIForContext(context);
            if (loginUri != null) {
                if (requestUri.getScheme().equals(loginUri.getScheme())
                        && requestUri.getHost().equals(loginUri.getHost())
                        && requestUri.getPort() == loginUri.getPort()
                        && requestUri.getPath().equals(loginUri.getPath())) {
                    // we got this far.. only the method (GET/POST), user details, query params,
                    // fragment, and POST params
                    // are possibly different from the login page.
                    loginUrl = true;
                    log.info(requestUri.toString()
                            + " falls within a context, and is the defined Login URL. Scanning for possible Username Enumeration vulnerability.");
                    break; // Stop checking
                }
            }
        }

        // the Username Enumeration scanner will only run for logon pages
        if (loginUrl == false) {
            if (this.debugEnabled) {
                log.debug(requestUri.toString() + " is not a defined Login URL.");
            }
            return; // No need to continue for this URL
        }

        // find all params set in the request (GET/POST/Cookie)
        TreeSet<HtmlParameter> htmlParams = new TreeSet<>();
        htmlParams.addAll(getBaseMsg().getRequestHeader().getCookieParams()); // request cookies only. no response cookies
        htmlParams.addAll(getBaseMsg().getFormParams()); // add in the POST params
        htmlParams.addAll(getBaseMsg().getUrlParams()); // add in the GET params

        int numberOfRequests = 0;
        if (this.getAttackStrength() == AttackStrength.INSANE) {
            numberOfRequests = 50;
        } else if (this.getAttackStrength() == AttackStrength.HIGH) {
            numberOfRequests = 15;
        } else if (this.getAttackStrength() == AttackStrength.MEDIUM) {
            numberOfRequests = 5;
        } else if (this.getAttackStrength() == AttackStrength.LOW) {
            numberOfRequests = 3;
        }

        // 1) Request the original URL n times. (The original URL is assumed to have a valid
        // username, if not a valid password). Store the results in A[].
        // make sure to manually handle all redirects, and cookies that may be set in response.
        // allocate enough space for the responses

        StringBuilder responseA = null;
        StringBuilder responseB = null;
        String longestCommonSubstringA = null;
        String longestCommonSubstringB = null;

        for (int i = 0; i < numberOfRequests; i++) {

            // initialise the storage for this iteration
            // baseResponses[i]= new StringBuilder(250);
            responseA = new StringBuilder(250);

            HttpMessage msgCpy = getNewMsg(); // clone the request, but not the response

            sendAndReceive(msgCpy, false, false); // request the URL, but do not automatically follow redirects.

            // get all cookies set in the response
            TreeSet<HtmlParameter> cookies = msgCpy.getResponseHeader().getCookieParams();

            int redirectCount = 0;
            while (HttpStatusCode.isRedirection(msgCpy.getResponseHeader().getStatusCode())) {
                redirectCount++;

                if (this.debugEnabled)
                    log.debug("Following redirect " + redirectCount + " for message " + i + " of "
                            + numberOfRequests + " iterations of the original query");

                // append the response to the responses so far for this particular instance
                // this will give us a complete picture of the full set of actual traffic
                // associated with following redirects for the request
                responseA.append(msgCpy.getResponseHeader().getHeadersAsString());
                responseA.append(msgCpy.getResponseBody().toString());

                // and manually follow the redirect
                // create a new message from scratch
                HttpMessage msgRedirect = new HttpMessage();

                // create a new URI from the absolute location returned, and interpret it as
                // escaped
                // note that the standard says that the Location returned should be absolute,
                // but it ain't always so...
                URI newLocation = new URI(msgCpy.getResponseHeader().getHeader(HttpHeader.LOCATION), true);
                try {
                    msgRedirect.getRequestHeader().setURI(newLocation);
                } catch (Exception e) {
                    // the Location field contents may not be standards compliant. Lets generate
                    // a uri to use as a workaround where a relative path was
                    // given instead of an absolute one
                    URI newLocationWorkaround = new URI(msgCpy.getRequestHeader().getURI(),
                            msgCpy.getResponseHeader().getHeader(HttpHeader.LOCATION), true);
                    // try again, except this time, if it fails, don't try to handle it
                    if (this.debugEnabled)
                        log.debug("The Location [" + newLocation
                                + "] specified in a redirect was not valid (not absolute?). Trying absolute workaround url ["
                                + newLocationWorkaround + "]");
                    msgRedirect.getRequestHeader().setURI(newLocationWorkaround);
                }
                msgRedirect.getRequestHeader().setMethod(HttpRequestHeader.GET); // it's always a GET for a redirect
                msgRedirect.getRequestHeader().setContentLength(0); // since we send a GET, the body will be 0 long
                if (cookies.size() > 0) {
                    // if a previous request sent back a cookie that has not since been
                    // invalidated, we need to set that cookie when following redirects, as a
                    // browser would
                    msgRedirect.getRequestHeader().setCookieParams(cookies);
                }

                if (this.debugEnabled)
                    log.debug("DEBUG: Following redirect to [" + newLocation + "]");
                sendAndReceive(msgRedirect, false, false); // do NOT redirect.. handle it here

                // handle scenario where a cookie is unset in a subsequent iteration, or where
                // the same cookie name is later re-assigned a different value
                // ie, in these cases, do not simply (and dumbly) accumulate cookie detritus.
                // first get all cookies set in the response
                TreeSet<HtmlParameter> cookiesTemp = msgRedirect.getResponseHeader().getCookieParams();
                for (Iterator<HtmlParameter> redirectSetsCookieIterator = cookiesTemp
                        .iterator(); redirectSetsCookieIterator.hasNext();) {
                    HtmlParameter cookieJustSet = redirectSetsCookieIterator.next();
                    // loop through each of the cookies we know about in cookies, to see if it
                    // matches by name.
                    // if so, delete that cookie, and add the one that was just set to cookies.
                    // if not, add the one that was just set to cookies.
                    for (Iterator<HtmlParameter> knownCookiesIterator = cookies.iterator(); knownCookiesIterator
                            .hasNext();) {
                        HtmlParameter knownCookie = knownCookiesIterator.next();
                        if (cookieJustSet.getName().equals(knownCookie.getName())) {
                            knownCookiesIterator.remove();
                            break; // out of the loop for known cookies, back to the next cookie
                            // set in the response
                        }
                    } // end of loop for cookies we already know about
                      // we can now safely add the cookie that was just set into cookies, knowing
                      // it does not clash with anything else in there.
                    cookies.add(cookieJustSet);
                } // end of for loop for cookies just set in the redirect

                msgCpy = msgRedirect; // store the last redirect message into the MsgCpy, as we
                // will be using it's output in a moment..
            } // end of loop to follow redirects

            // now that the redirections have all been handled.. was the request finally a
            // success or not?  Successful or Failed Logins would normally both return an OK
            // HTTP status
            if (!HttpStatusCode.isSuccess(msgCpy.getResponseHeader().getStatusCode())) {
                log.warn("The original URL [" + getBaseMsg().getRequestHeader().getURI()
                        + "] returned a non-OK HTTP status " + msgCpy.getResponseHeader().getStatusCode()
                        + " (after " + i + " of " + numberOfRequests
                        + " steps). Could be indicative of SQL Injection, or some other error. The URL is not stable enough to look at Username Enumeration");
                return; // we have not even got as far as looking at the parameters, so just
                // abort straight out of the method
            }

            if (this.debugEnabled)
                log.debug("Done following redirects!");

            // append the response to the responses so far for this particular instance
            // this will give us a complete picture of the full set of actual traffic associated
            // with following redirects for the request
            responseA.append(msgCpy.getResponseHeader().getHeadersAsString());
            responseA.append(msgCpy.getResponseBody().toString());

            // 2) Compute the longest common subsequence (LCS) of A[] into LCS_A
            // Note: in the Freiling and Schinzel method, this is calculated recursively. We
            // calculate it iteratively, but using an equivalent method

            // first time in, the LCS is simple: it's the first HTML result.. no diffing
            // required
            if (i == 0)
                longestCommonSubstringA = responseA.toString();
            // else get the LCS of the existing string, and the current result
            else
                longestCommonSubstringA = this.longestCommonSubsequence(longestCommonSubstringA,
                        responseA.toString());

            // optimisation step: if the LCS of A is 0 characters long already, then the URL
            // output is not stable, and we can abort now, and save some time
            if (longestCommonSubstringA.length() == 0) {
                // this might occur if the output returned for the URL changed mid-way. Perhaps
                // a CAPTCHA has fired, or a WAF has kicked in.  Let's abort now so.
                log.warn("The original URL [" + getBaseMsg().getRequestHeader().getURI()
                        + "] does not produce stable output (at " + i + 1 + " of " + numberOfRequests
                        + " steps). There is no static element in the output that can be used as a basis of comparison for the result of requesting URLs with the parameter values modified. Perhaps a CAPTCHA or WAF has kicked in!!");
                return; // we have not even got as far as looking at the parameters, so just
                // abort straight out of the method
            }
        }
        // get rid of any remnants of cookie setting and Date headers in the responses, as these
        // cause false positives, and can be safely ignored
        // replace the content length with a non-variable placeholder
        // replace url parameters with a non-variable placeholder to eliminate tokens in URLs in
        // the output
        longestCommonSubstringA = longestCommonSubstringA.replaceAll("Set-Cookie:[^\\r\\n]+[\\r\\n]{1,2}", "");
        longestCommonSubstringA = longestCommonSubstringA.replaceAll("Date:[^\\r\\n]+[\\r\\n]{1,2}", "");
        longestCommonSubstringA = longestCommonSubstringA.replaceAll("Content-Length:[^\\r\\n]+[\\r\\n]{1,2}",
                "Content-Length: XXXX\n");
        longestCommonSubstringA = longestCommonSubstringA
                .replaceAll("(?<=(&amp;|\\?)[^\\?\"=&;]+=)[^\\?\"=&;]+(?=(&amp;|\"))", "YYYY");

        if (this.debugEnabled)
            log.debug("The LCS of A is [" + longestCommonSubstringA + "]");

        // 3) for each parameter in the original URL (ie, for URL params, form params, and
        // cookie params)
        for (Iterator<HtmlParameter> iter = htmlParams.iterator(); iter.hasNext();) {

            HttpMessage msgModifiedParam = getNewMsg();
            HtmlParameter currentHtmlParameter = iter.next();

            if (this.debugEnabled)
                log.debug("Handling [" + currentHtmlParameter.getType() + "] parameter ["
                        + currentHtmlParameter.getName() + "], with value [" + currentHtmlParameter.getValue()
                        + "]");

            // 4) Change the current parameter value (which we assume is the username parameter)
            // to an invalid username (randomly), and request the URL n times. Store the results
            // in B[].

            // get a random user name the same length as the original!
            String invalidUsername = RandomStringUtils.random(currentHtmlParameter.getValue().length(),
                    RANDOM_USERNAME_CHARS);
            if (this.debugEnabled)
                log.debug("The invalid username chosen was [" + invalidUsername + "]");

            TreeSet<HtmlParameter> requestParams = null;
            if (currentHtmlParameter.getType().equals(HtmlParameter.Type.cookie)) {
                requestParams = msgModifiedParam.getRequestHeader().getCookieParams();
                requestParams.remove(currentHtmlParameter);
                requestParams.add(new HtmlParameter(currentHtmlParameter.getType(),
                        currentHtmlParameter.getName(), invalidUsername.toString())); // add in the invalid username
                msgModifiedParam.setCookieParams(requestParams);
            } else if (currentHtmlParameter.getType().equals(HtmlParameter.Type.url)) {
                requestParams = msgModifiedParam.getUrlParams();
                requestParams.remove(currentHtmlParameter);
                requestParams.add(new HtmlParameter(currentHtmlParameter.getType(),
                        currentHtmlParameter.getName(), invalidUsername.toString())); // add in the invalid username
                msgModifiedParam.setGetParams(requestParams);
            } else if (currentHtmlParameter.getType().equals(HtmlParameter.Type.form)) {
                requestParams = msgModifiedParam.getFormParams();
                requestParams.remove(currentHtmlParameter);
                requestParams.add(new HtmlParameter(currentHtmlParameter.getType(),
                        currentHtmlParameter.getName(), invalidUsername.toString())); // add in the invalid username
                msgModifiedParam.setFormParams(requestParams);
            }

            if (this.debugEnabled)
                log.debug("About to loop for " + numberOfRequests
                        + " iterations with an incorrect user of the same length");

            boolean continueForParameter = true;
            for (int i = 0; i < numberOfRequests && continueForParameter; i++) {

                // initialise the storage for this iteration
                responseB = new StringBuilder(250);

                HttpMessage msgCpy = msgModifiedParam; // use the message we already set up, with the
                // modified parameter value

                sendAndReceive(msgCpy, false, false); // request the URL, but do not automatically follow redirects.

                // get all cookies set in the response
                TreeSet<HtmlParameter> cookies = msgCpy.getResponseHeader().getCookieParams();

                int redirectCount = 0;
                while (HttpStatusCode.isRedirection(msgCpy.getResponseHeader().getStatusCode())) {
                    redirectCount++;

                    if (this.debugEnabled)
                        log.debug("Following redirect " + redirectCount + " for message " + i + " of "
                                + numberOfRequests + " iterations of the modified query");

                    // append the response to the responses so far for this particular instance
                    // this will give us a complete picture of the full set of actual traffic
                    // associated with following redirects for the request
                    responseB.append(msgCpy.getResponseHeader().getHeadersAsString());
                    responseB.append(msgCpy.getResponseBody().toString());

                    // and manually follow the redirect
                    // create a new message from scratch
                    HttpMessage msgRedirect = new HttpMessage();

                    // create a new URI from the absolute location returned, and interpret it as
                    // escaped
                    // note that the standard says that the Location returned should be
                    // absolute, but it ain't always so...
                    URI newLocation = new URI(msgCpy.getResponseHeader().getHeader(HttpHeader.LOCATION), true);
                    try {
                        msgRedirect.getRequestHeader().setURI(newLocation);
                    } catch (Exception e) {
                        // the Location field contents may not be standards compliant. Lets
                        // generate a uri to use as a workaround where a relative path was
                        // given instead of an absolute one
                        URI newLocationWorkaround = new URI(msgCpy.getRequestHeader().getURI(),
                                msgCpy.getResponseHeader().getHeader(HttpHeader.LOCATION), true);
                        // try again, except this time, if it fails, don't try to handle it
                        if (this.debugEnabled)
                            log.debug("The Location [" + newLocation
                                    + "] specified in a redirect was not valid (not absolute?). Trying absolute workaround url ["
                                    + newLocationWorkaround + "]");
                        msgRedirect.getRequestHeader().setURI(newLocationWorkaround);
                    }
                    msgRedirect.getRequestHeader().setMethod(HttpRequestHeader.GET); // it's always a GET for a redirect
                    msgRedirect.getRequestHeader().setContentLength(0); // since we send a GET, the body will be 0 long
                    if (cookies.size() > 0) {
                        // if a previous request sent back a cookie that has not since been
                        // invalidated, we need to set that cookie when following redirects, as
                        // a browser would
                        msgRedirect.getRequestHeader().setCookieParams(cookies);
                    }

                    sendAndReceive(msgRedirect, false, false); // do NOT redirect.. handle it here

                    // handle scenario where a cookie is unset in a subsequent iteration, or
                    // where the same cookie name is later re-assigned a different value
                    // ie, in these cases, do not simply (and dumbly) accumulate cookie
                    // detritus.
                    // first get all cookies set in the response
                    TreeSet<HtmlParameter> cookiesTemp = msgRedirect.getResponseHeader().getCookieParams();
                    for (Iterator<HtmlParameter> redirectSetsCookieIterator = cookiesTemp
                            .iterator(); redirectSetsCookieIterator.hasNext();) {
                        HtmlParameter cookieJustSet = redirectSetsCookieIterator.next();
                        // loop through each of the cookies we know about in cookies, to see if
                        // it matches by name.
                        // if so, delete that cookie, and add the one that was just set to
                        // cookies.
                        // if not, add the one that was just set to cookies.
                        for (Iterator<HtmlParameter> knownCookiesIterator = cookies
                                .iterator(); knownCookiesIterator.hasNext();) {
                            HtmlParameter knownCookie = knownCookiesIterator.next();
                            if (cookieJustSet.getName().equals(knownCookie.getName())) {
                                knownCookiesIterator.remove();
                                break; // out of the loop for known cookies, back to the next
                                // cookie set in the response
                            }
                        } // end of loop for cookies we already know about
                          // we can now safely add the cookie that was just set into cookies,
                          // knowing it does not clash with anything else in there.
                        cookies.add(cookieJustSet);
                    } // end of for loop for cookies just set in the redirect

                    msgCpy = msgRedirect; // store the last redirect message into the MsgCpy, as
                    // we will be using it's output in a moment..
                } // end of loop to follow redirects

                // now that the redirections have all been handled.. was the request finally a
                // success or not?  Successful or Failed Logins would normally both return an OK
                // HTTP status
                if (!HttpStatusCode.isSuccess(msgCpy.getResponseHeader().getStatusCode())) {
                    log.warn("The modified URL [" + msgModifiedParam.getRequestHeader().getURI()
                            + "] returned a non-OK HTTP status " + msgCpy.getResponseHeader().getStatusCode()
                            + " (after " + i + 1 + " of " + numberOfRequests + " steps for ["
                            + currentHtmlParameter.getType() + "] parameter " + currentHtmlParameter.getName()
                            + "). Could be indicative of SQL Injection, or some other error. The URL is not stable enough to look at Username Enumeration");
                    continueForParameter = false;
                    continue; // skip directly to the next parameter. Do not pass Go. Do not
                    // collect $200.
                }

                if (this.debugEnabled)
                    log.debug("Done following redirects!");

                // append the response to the responses so far for this particular instance
                // this will give us a complete picture of the full set of actual traffic
                // associated with following redirects for the request
                responseB.append(msgCpy.getResponseHeader().getHeadersAsString());
                responseB.append(msgCpy.getResponseBody().toString());

                // 5) Compute the longest common subsequence (LCS) of B[] into LCS_B
                // Note: in the Freiling and Schinzel method, this is calculated recursively. We
                // calculate it iteratively, but using an equivalent method

                // first time in, the LCS is simple: it's the first HTML result.. no diffing
                // required
                if (i == 0)
                    longestCommonSubstringB = responseB.toString();
                // else get the LCS of the existing string, and the current result
                else
                    longestCommonSubstringB = this.longestCommonSubsequence(longestCommonSubstringB,
                            responseB.toString());

                // optimisation step: if the LCS of B is 0 characters long already, then the URL
                // output is not stable, and we can abort now, and save some time
                if (longestCommonSubstringB.length() == 0) {
                    // this might occur if the output returned for the URL changed mid-way.
                    // Perhaps a CAPTCHA has fired, or a WAF has kicked in.  Let's abort now so.
                    log.warn("The modified URL [" + msgModifiedParam.getRequestHeader().getURI() + "] (for ["
                            + currentHtmlParameter.getType() + "] parameter " + currentHtmlParameter.getName()
                            + ") does not produce stable output (after " + i + 1 + " of " + numberOfRequests
                            + " steps). There is no static element in the output that can be used as a basis of comparison with the static output of the original query. Perhaps a CAPTCHA or WAF has kicked in!!");
                    continueForParameter = false;
                    continue; // skip directly to the next parameter. Do not pass Go. Do not
                    // collect $200.
                    // Note: if a CAPTCHA or WAF really has fired, the results of subsequent
                    // iterations will likely not be accurate..
                }
            }

            // if we didn't hit something with one of the iterations for the parameter (ie, if
            // the output when changing the parm is stable),
            // check if the parameter might be vulnerable by comparins its LCS with the original
            // LCS for a valid login
            if (continueForParameter == true) {
                // get rid of any remnants of cookie setting and Date headers in the responses,
                // as these cause false positives, and can be safely ignored
                // replace the content length with a non-variable placeholder
                // replace url parameters with a non-variable placeholder to eliminate tokens in
                // URLs in the output
                longestCommonSubstringB = longestCommonSubstringB
                        .replaceAll("Set-Cookie:[^\\r\\n]+[\\r\\n]{1,2}", "");
                longestCommonSubstringB = longestCommonSubstringB.replaceAll("Date:[^\\r\\n]+[\\r\\n]{1,2}",
                        "");
                longestCommonSubstringB = longestCommonSubstringB
                        .replaceAll("Content-Length:[^\\r\\n]+[\\r\\n]{1,2}", "Content-Length: XXXX\n");
                longestCommonSubstringB = longestCommonSubstringB
                        .replaceAll("(?<=(&amp;|\\?)[^\\?\"=&;]+=)[^\\?\"=&;]+(?=(&amp;|\"))", "YYYY");

                if (this.debugEnabled)
                    log.debug("The LCS of B is [" + longestCommonSubstringB + "]");

                // 6) If LCS_A <> LCS_B, then there is a Username Enumeration issue on the
                // current parameter
                if (!longestCommonSubstringA.equals(longestCommonSubstringB)) {
                    // calculate line level diffs of the 2 Longest Common Substrings to aid the
                    // user in deciding if the match is a false positive
                    // get the diff as a series of patches
                    Patch diffpatch = DiffUtils.diff(
                            new LinkedList<String>(Arrays.asList(longestCommonSubstringA.split("\\n"))),
                            new LinkedList<String>(Arrays.asList(longestCommonSubstringB.split("\\n"))));

                    int numberofDifferences = diffpatch.getDeltas().size();

                    // and convert the list of patches to a String, joining using a newline
                    // String diffAB = StringUtils.join(diffpatch.getDeltas(), "\n");
                    StringBuilder tempDiff = new StringBuilder(250);
                    for (Delta delta : diffpatch.getDeltas()) {
                        String changeType = null;
                        if (delta.getType() == Delta.TYPE.CHANGE)
                            changeType = "Changed Text";
                        else if (delta.getType() == Delta.TYPE.DELETE)
                            changeType = "Deleted Text";
                        else if (delta.getType() == Delta.TYPE.INSERT)
                            changeType = "Inserted text";
                        else
                            changeType = "Unknown change type [" + delta.getType() + "]";

                        tempDiff.append("\n(" + changeType + ")\n"); // blank line before
                        tempDiff.append("Output for Valid Username  : " + delta.getOriginal() + "\n"); // no blank lines
                        tempDiff.append("\nOutput for Invalid Username: " + delta.getRevised() + "\n"); // blank line before
                    }
                    String diffAB = tempDiff.toString();
                    String extraInfo = Constant.messages.getString(
                            "ascanbeta.usernameenumeration.alert.extrainfo", currentHtmlParameter.getType(),
                            currentHtmlParameter.getName(), currentHtmlParameter.getValue(), // original value
                            invalidUsername.toString(), // new value
                            diffAB, // the differences between the two sets of output
                            numberofDifferences); // the number of differences
                    String attack = Constant.messages.getString("ascanbeta.usernameenumeration.alert.attack",
                            currentHtmlParameter.getType(), currentHtmlParameter.getName());
                    String vulnname = Constant.messages.getString("ascanbeta.usernameenumeration.name");
                    String vulndesc = Constant.messages.getString("ascanbeta.usernameenumeration.desc");
                    String vulnsoln = Constant.messages.getString("ascanbeta.usernameenumeration.soln");

                    // call bingo with some extra info, indicating that the alert is
                    bingo(Alert.RISK_INFO, Alert.CONFIDENCE_LOW, vulnname, vulndesc,
                            getBaseMsg().getRequestHeader().getURI().getURI(), currentHtmlParameter.getName(),
                            attack, extraInfo, vulnsoln, getBaseMsg());

                } else {
                    if (this.debugEnabled)
                        log.debug("[" + currentHtmlParameter.getType() + "] parameter ["
                                + currentHtmlParameter.getName()
                                + "] looks ok (Invalid Usernames cannot be distinguished from Valid usernames)");
                }
            }
        } // end of the for loop around the parameter list

    } catch (Exception e) {
        // Do not try to internationalise this.. we need an error message in any event..
        // if it's in English, it's still better than not having it at all.
        log.error("An error occurred checking a url for Username Enumeration issues", e);
    }
}

From source file:org.unitime.timetable.backup.SessionBackup.java

@Override
public void backup(OutputStream out, Progress progress, Long sessionId) throws IOException {
    iOut = CodedOutputStream.newInstance(out);
    iProgress = progress;/*from  w ww. j  a  v  a2  s.  c  om*/
    iSessionId = sessionId;
    iHibSession = new _RootDAO().createNewSession();
    iHibSession.setCacheMode(CacheMode.IGNORE);
    iHibSessionFactory = iHibSession.getSessionFactory();
    try {
        iProgress.setStatus("Exporting Session");
        iProgress.setPhase("Loading Model", 3);
        TreeSet<ClassMetadata> allMeta = new TreeSet<ClassMetadata>(new Comparator<ClassMetadata>() {
            @Override
            public int compare(ClassMetadata m1, ClassMetadata m2) {
                return m1.getEntityName().compareTo(m2.getEntityName());
            }
        });
        allMeta.addAll(iHibSessionFactory.getAllClassMetadata().values());
        iProgress.incProgress();

        Queue<QueueItem> queue = new LinkedList<QueueItem>();

        queue.add(new QueueItem(iHibSessionFactory.getClassMetadata(Session.class), null, "uniqueId",
                Relation.None));

        Set<String> avoid = new HashSet<String>();
        // avoid following relations
        avoid.add(TimetableManager.class.getName() + ".departments");
        avoid.add(TimetableManager.class.getName() + ".solverGroups");
        avoid.add(DistributionType.class.getName() + ".departments");
        avoid.add(LastLikeCourseDemand.class.getName() + ".student");
        avoid.add(Student.class.getName() + ".lastLikeCourseDemands");

        Set<String> disallowedNotNullRelations = new HashSet<String>();
        disallowedNotNullRelations.add(Assignment.class.getName() + ".datePattern");
        disallowedNotNullRelations.add(Assignment.class.getName() + ".timePattern");
        disallowedNotNullRelations.add(LastLikeCourseDemand.class.getName() + ".student");
        disallowedNotNullRelations.add(OnlineSectioningLog.class.getName() + ".session");

        Map<String, List<QueueItem>> data = new HashMap<String, List<QueueItem>>();
        List<QueueItem> sessions = new ArrayList<QueueItem>();
        sessions.add(queue.peek());
        data.put(queue.peek().name(), sessions);

        QueueItem item = null;
        while ((item = queue.poll()) != null) {
            if (item.size() == 0)
                continue;
            for (ClassMetadata meta : allMeta) {
                if (meta.hasSubclasses())
                    continue;
                for (int i = 0; i < meta.getPropertyNames().length; i++) {
                    String property = meta.getPropertyNames()[i];
                    if (disallowedNotNullRelations.contains(meta.getEntityName() + "." + property)
                            || meta.getPropertyNullability()[i])
                        continue;
                    Type type = meta.getPropertyTypes()[i];
                    if (type instanceof EntityType && type.getReturnedClass().equals(item.clazz())) {
                        QueueItem qi = new QueueItem(meta, item, property, Relation.Parent);
                        if (!data.containsKey(qi.name())) {
                            List<QueueItem> items = new ArrayList<QueueItem>();
                            data.put(qi.name(), items);
                            queue.add(qi);
                            items.add(qi);
                            if (qi.size() > 0)
                                iProgress.info("Parent: " + qi);
                        }
                    }
                }
            }
        }
        iProgress.incProgress();

        for (List<QueueItem> list : data.values())
            queue.addAll(list);

        // The following part is needed to ensure that instructor distribution preferences are saved including their distribution types 
        List<QueueItem> distributions = new ArrayList<QueueItem>();
        for (QueueItem instructor : data.get(DepartmentalInstructor.class.getName())) {
            QueueItem qi = new QueueItem(iHibSessionFactory.getClassMetadata(DistributionPref.class),
                    instructor, "owner", Relation.Parent);
            distributions.add(qi);
            queue.add(qi);
            if (qi.size() > 0)
                iProgress.info("Extra: " + qi);
        }
        data.put(DistributionPref.class.getName(), distributions);

        while ((item = queue.poll()) != null) {
            if (item.size() == 0)
                continue;
            for (int i = 0; i < item.meta().getPropertyNames().length; i++) {
                String property = item.meta().getPropertyNames()[i];
                Type type = item.meta().getPropertyTypes()[i];
                if (type instanceof EntityType) {
                    if (avoid.contains(item.name() + "." + property))
                        continue;

                    ClassMetadata meta = iHibSessionFactory.getClassMetadata(type.getReturnedClass());
                    if (item.contains(meta.getEntityName()))
                        continue;

                    QueueItem qi = new QueueItem(meta, item, property, Relation.One);
                    List<QueueItem> items = data.get(qi.name());
                    if (items == null) {
                        items = new ArrayList<QueueItem>();
                        data.put(qi.name(), items);
                    }
                    queue.add(qi);
                    items.add(qi);

                    if (qi.size() > 0)
                        iProgress.info("One: " + qi);
                }
                if (type instanceof CollectionType) {
                    if (avoid.contains(item.name() + "." + property))
                        continue;

                    ClassMetadata meta = iHibSessionFactory.getClassMetadata(((CollectionType) type)
                            .getElementType((SessionFactoryImplementor) iHibSessionFactory).getReturnedClass());
                    if (meta == null || item.contains(meta.getEntityName()))
                        continue;

                    QueueItem qi = new QueueItem(meta, item, property, Relation.Many);
                    List<QueueItem> items = data.get(qi.name());
                    if (items == null) {
                        items = new ArrayList<QueueItem>();
                        data.put(qi.name(), items);
                    }
                    queue.add(qi);
                    items.add(qi);

                    if (qi.size() > 0)
                        iProgress.info("Many: " + qi);
                }
            }
        }
        iProgress.incProgress();

        Map<String, Set<Serializable>> allExportedIds = new HashMap<String, Set<Serializable>>();
        for (String name : new TreeSet<String>(data.keySet())) {
            List<QueueItem> list = data.get(name);
            Map<String, TableData.Table.Builder> tables = new HashMap<String, TableData.Table.Builder>();
            for (QueueItem current : list) {
                if (current.size() == 0)
                    continue;
                iProgress.info("Loading " + current);
                List<Object> objects = current.list();
                if (objects == null || objects.isEmpty())
                    continue;
                iProgress.setPhase(current.abbv() + " [" + objects.size() + "]", objects.size());
                objects: for (Object object : objects) {
                    iProgress.incProgress();

                    // Get meta data (check for sub-classes)
                    ClassMetadata meta = iHibSessionFactory.getClassMetadata(object.getClass());
                    if (meta == null)
                        meta = current.meta();
                    if (meta.hasSubclasses()) {
                        for (Iterator i = iHibSessionFactory.getAllClassMetadata().entrySet().iterator(); i
                                .hasNext();) {
                            Map.Entry entry = (Map.Entry) i.next();
                            ClassMetadata classMetadata = (ClassMetadata) entry.getValue();
                            if (classMetadata.getMappedClass().isInstance(object)
                                    && !classMetadata.hasSubclasses()) {
                                meta = classMetadata;
                                break;
                            }
                        }
                    }

                    // Get unique identifier
                    Serializable id = meta.getIdentifier(object, (SessionImplementor) iHibSession);

                    // Check if already exported
                    Set<Serializable> exportedIds = allExportedIds.get(meta.getEntityName());
                    if (exportedIds == null) {
                        exportedIds = new HashSet<Serializable>();
                        allExportedIds.put(meta.getEntityName(), exportedIds);
                    }
                    if (!exportedIds.add(id))
                        continue;

                    // Check relation to an academic session (if exists)
                    for (String property : meta.getPropertyNames()) {
                        Type type = meta.getPropertyType(property);
                        if (type instanceof EntityType && type.getReturnedClass().equals(Session.class)) {
                            Session s = (Session) meta.getPropertyValue(object, property);
                            if (s != null && !s.getUniqueId().equals(iSessionId)) {
                                iProgress.warn(meta.getEntityName()
                                        .substring(meta.getEntityName().lastIndexOf('.') + 1) + "@" + id
                                        + " belongs to a different academic session (" + s + ")");
                                continue objects; // wrong session
                            }
                        }
                    }

                    // Get appropriate table
                    TableData.Table.Builder table = tables.get(meta.getEntityName());
                    if (table == null) {
                        table = TableData.Table.newBuilder();
                        tables.put(meta.getEntityName(), table);
                        table.setName(meta.getEntityName());
                    }

                    // Export object
                    TableData.Record.Builder record = TableData.Record.newBuilder();
                    record.setId(id.toString());
                    for (String property : meta.getPropertyNames()) {
                        Type type = meta.getPropertyType(property);
                        Object value = meta.getPropertyValue(object, property);
                        if (value == null)
                            continue;
                        TableData.Element.Builder element = TableData.Element.newBuilder();
                        element.setName(property);
                        if (type instanceof PrimitiveType) {
                            element.addValue(((PrimitiveType) type).toString(value));
                        } else if (type instanceof StringType) {
                            element.addValue(((StringType) type).toString((String) value));
                        } else if (type instanceof BinaryType) {
                            element.addValueBytes(ByteString.copyFrom((byte[]) value));
                        } else if (type instanceof TimestampType) {
                            element.addValue(((TimestampType) type).toString((Date) value));
                        } else if (type instanceof DateType) {
                            element.addValue(((DateType) type).toString((Date) value));
                        } else if (type instanceof EntityType) {
                            List<Object> ids = current.relation(property, id, false);
                            if (ids != null)
                                for (Object i : ids)
                                    element.addValue(i.toString());
                            iHibSession.evict(value);
                        } else if (type instanceof CustomType && value instanceof Document) {
                            if (object instanceof CurriculumClassification && property.equals("students"))
                                continue;
                            StringWriter w = new StringWriter();
                            XMLWriter x = new XMLWriter(w, OutputFormat.createCompactFormat());
                            x.write((Document) value);
                            x.flush();
                            x.close();
                            element.addValue(w.toString());
                        } else if (type instanceof CollectionType) {
                            List<Object> ids = current.relation(property, id, false);
                            if (ids != null)
                                for (Object i : ids)
                                    element.addValue(i.toString());
                        } else if (type instanceof EmbeddedComponentType
                                && property.equalsIgnoreCase("uniqueCourseNbr")) {
                            continue;
                        } else {
                            iProgress.warn("Unknown data type: " + type + " (property " + meta.getEntityName()
                                    + "." + property + ", class " + value.getClass() + ")");
                            continue;
                        }
                        record.addElement(element.build());

                    }
                    table.addRecord(record.build());
                    iHibSession.evict(object);
                }
                current.clearCache();
            }

            for (TableData.Table.Builder table : tables.values()) {
                add(table.build());
            }
        }

        /*
        // Skip ConstraintInfo
        if (!iData.containsKey(ConstraintInfo.class.getName()))
           iData.put(ConstraintInfo.class.getName(), new QueueItem(iHibSessionFactory.getClassMetadata(ConstraintInfo.class), null, null, Relation.Empty));
                
        for (String name: items)
           export(iData.get(name));
                    
        while (true) {
         List<Object> objects = new ArrayList<Object>();
         ClassMetadata meta = null;
         for (Entity e: iObjects) {
        if (e.exported()) continue;
        if (objects.isEmpty() || meta.getEntityName().equals(e.name())) {
           meta = e.meta();
           objects.add(e.object());
           e.notifyExported();
        }
         }
         if (objects.isEmpty()) break;
         export(meta, objects, null);
        }
        */
        iProgress.setStatus("All done.");
    } finally {
        iHibSession.close();
    }
}