Example usage for java.util LinkedList clear

List of usage examples for java.util LinkedList clear

Introduction

In this page you can find the example usage for java.util LinkedList clear.

Prototype

public void clear() 

Source Link

Document

Removes all of the elements from this list.

Usage

From source file:org.opendaylight.vtn.manager.it.northbound.VtnNorthboundIT.java

/**
 * Test case for MAC mapping APIs.//www  .j  a  v  a  2 s  .co m
 *
 * <p>
 *   This method is called by {@link #testVBridgeAPI(String, String)}.
 * </p>
 *
 * @param tname   The name of existing virtual tenant.
 * @param bname1  The name of existing vBridge.
 * @param bname2  The name of existing vBridge.
 * @throws JSONException  An error occurred.
 */
private void testMacMappingAPI(String tname, String bname1, String bname2) throws JSONException {
    LOG.info("Starting MAC Mapping JAX-RS client.");

    String qparam = "?param1=1&param2=2";
    String mapUri = createURI("default/vtns", tname, "vbridges", bname1, "macmap");
    String mapUri2 = createURI("default/vtns", tname, "vbridges", bname2, "macmap");

    // Ensure that no MAC mapping is configured.
    assertNoMacMapping(mapUri);
    assertNoMacMapping(mapUri2);

    LinkedList<String> allowedHosts = new LinkedList<String>();
    allowedHosts.add(null);
    allowedHosts.add(null);

    byte[] allowedAddr = { (byte) 0x10, (byte) 0x20, (byte) 0x30, (byte) 0x40, (byte) 0x50, (byte) 0x00, };

    for (int i = 0; i < 20; i++) {
        String mac;
        if ((i & 1) == 0) {
            mac = null;
        } else {
            allowedAddr[5] = (byte) i;
            mac = ByteUtils.toHexString(allowedAddr);
        }

        String vlan = (i == 0) ? "4095" : String.valueOf(i);
        allowedHosts.add(mac);
        allowedHosts.add(vlan);
    }

    LinkedList<String> deniedHosts = new LinkedList<String>();
    byte[] deniedAddr = { (byte) 0xf0, (byte) 0xf1, (byte) 0xf2, (byte) 0xf3, (byte) 0x00, (byte) 0xf5, };

    for (int i = 0; i < 20; i++) {
        deniedAddr[4] = (byte) i;
        String mac = ByteUtils.toHexString(deniedAddr);
        String vlan = String.valueOf(i + 100);
        deniedHosts.add(mac);
        deniedHosts.add(vlan);
    }
    deniedHosts.add("00:00:ff:ff:ff:0f");
    deniedHosts.add(null);

    // Install MAC mapping configuration.
    JSONObject config = createMacMapConfig(allowedHosts, deniedHosts);
    JSONObject configExpected = completeMacMapConfig(config);

    String cf = config.toString();
    getJsonResult(mapUri + qparam, HTTP_PUT, cf);
    assertResponse(HTTP_CREATED);
    Assert.assertEquals(mapUri, httpLocation);

    for (String method : new String[] { HTTP_PUT, HTTP_POST }) {
        getJsonResult(mapUri, method, cf);
        assertResponse(HTTP_NO_CONTENT);
    }

    assertMacMapping(mapUri, configExpected);

    // Try to create MAC mapping with specifying invalid MAC address.
    String[] badMacs = {
            // broken
            "invalid_mac_address",
            // zero
            "00:00:00:00:00:00",
            // broadcast
            "ff:ff:ff:ff:ff:ff",
            // multicast
            "81:00:11:22:33:44", };

    String[] acls = { "allow", "deny" };
    for (String mac : badMacs) {
        JSONObject machost = new JSONObject();
        machost.put("address", mac);
        machost.put("vlan", 1);

        JSONArray maclist = new JSONArray();
        maclist.put(machost);

        JSONObject set = new JSONObject();
        set.put("machost", maclist);

        for (String acl : acls) {
            String uri = createRelativeURI(mapUri, acl, mac, "1");
            getJsonResult(uri, HTTP_PUT);
            assertResponse(HTTP_BAD_REQUEST);

            for (String method : new String[] { HTTP_PUT, HTTP_POST }) {
                JSONObject conf = new JSONObject();
                conf.put(acl, set);

                getJsonResult(mapUri, method, conf.toString());
                assertResponse(HTTP_BAD_REQUEST);

                uri = createRelativeURI(mapUri, acl);
                getJsonResult(uri, method, set.toString());
                assertResponse(HTTP_BAD_REQUEST);
            }
        }
    }

    // Try to create MAC mapping with specifying invalid VLAN ID.
    int[] badVlans = { -1, 4096, 10000, };

    for (int vlan : badVlans) {
        String mac = "00:00:00:00:00:10";
        JSONObject machost = new JSONObject();
        machost.put("address", mac);
        machost.put("vlan", vlan);

        JSONArray maclist = new JSONArray();
        maclist.put(machost);

        JSONObject set = new JSONObject();
        set.put("machost", maclist);

        for (String acl : acls) {
            String uri = createRelativeURI(mapUri, acl, mac, String.valueOf(vlan));
            getJsonResult(uri, HTTP_PUT);
            assertResponse(HTTP_BAD_REQUEST);

            for (String method : new String[] { HTTP_PUT, HTTP_POST }) {
                JSONObject conf = new JSONObject();
                conf.put(acl, set);

                getJsonResult(mapUri, method, conf.toString());
                assertResponse(HTTP_BAD_REQUEST);

                uri = createRelativeURI(mapUri, acl);
                getJsonResult(uri, method, set.toString());
                assertResponse(HTTP_BAD_REQUEST);
            }
        }
    }

    // Try to register NULL address to deny set.
    for (String method : new String[] { HTTP_POST, HTTP_PUT }) {
        String acl = "deny";
        JSONObject set = createMacHostSet(null, "110");
        JSONObject conf = new JSONObject();
        conf.put(acl, set);

        getJsonResult(mapUri, method, conf.toString());
        assertResponse(HTTP_BAD_REQUEST);

        String uri = createRelativeURI(mapUri, acl);
        getJsonResult(uri, method, set.toString());
        assertResponse(HTTP_BAD_REQUEST);
    }

    // Try to remove hosts that are not registered.
    String remove = "?action=remove";
    LinkedList<String> allowedHosts1 = new LinkedList<String>();
    for (int i = 0; i < 5; i++) {
        String mac;
        if ((i & 1) == 0) {
            mac = null;
        } else {
            allowedAddr[5] = (byte) i;
            mac = ByteUtils.toHexString(allowedAddr);
        }

        String vlan = String.valueOf(i + 100);
        allowedHosts1.add(mac);
        allowedHosts1.add(vlan);
    }

    for (int i = 5; i < 10; i++) {
        String mac;
        if ((i & 1) == 0) {
            allowedAddr[5] = (byte) (i + 1);
            mac = ByteUtils.toHexString(allowedAddr);
        } else {
            mac = null;
        }

        String vlan = String.valueOf(i);
        allowedHosts1.add(mac);
        allowedHosts1.add(vlan);
    }

    LinkedList<String> deniedHosts1 = new LinkedList<String>();
    for (int i = 0; i < 5; i++) {
        deniedAddr[4] = (byte) (i + 1);
        String mac = ByteUtils.toHexString(deniedAddr);
        String vlan = String.valueOf(i + 100);
        deniedHosts1.add(mac);
        deniedHosts1.add(vlan);
    }
    for (int i = 5; i < 10; i++) {
        deniedAddr[4] = (byte) i;
        String mac = ByteUtils.toHexString(deniedAddr);
        String vlan = String.valueOf(i + 1000);
        deniedHosts1.add(mac);
        deniedHosts1.add(vlan);
    }

    JSONObject allow1 = createMacHostSet(allowedHosts1);
    JSONObject deny1 = createMacHostSet(deniedHosts1);
    config = new JSONObject();
    config.put("allow", allow1).put("deny", deny1);
    getJsonResult(createRelativeURI(mapUri + remove), HTTP_POST, config.toString());
    assertResponse(HTTP_NO_CONTENT);
    for (String acl : acls) {
        JSONObject set;
        LinkedList<String> hostList;
        if (acl.equals("allow")) {
            set = allow1;
            hostList = allowedHosts1;
        } else {
            set = deny1;
            hostList = deniedHosts1;
        }

        getJsonResult(createRelativeURI(mapUri, acl + remove), HTTP_POST, set.toString());
        assertResponse(HTTP_NO_CONTENT);

        Iterator<String> it = hostList.iterator();
        while (it.hasNext()) {
            String m = it.next();
            String v = it.next();
            String uri = createRelativeURI(mapUri, acl, (m == null) ? "ANY" : m, (v == null) ? "0" : v);
            getJsonResult(uri, HTTP_DELETE);
            assertResponse(HTTP_NO_CONTENT);
        }
    }

    String[] allowedArray = allowedHosts.toArray(new String[0]);
    for (int i = 0; i < allowedArray.length; i += 2) {
        String acl = "allow";
        String mac = allowedArray[i];
        String vlan = allowedArray[i + 1];

        // Try to map MAC addresses which are already mapped by another
        // vBridge.
        String uri = createRelativeURI(mapUri2, acl, (mac == null) ? "ANY" : mac, (vlan == null) ? "0" : vlan);
        getJsonResult(uri, HTTP_PUT);
        assertResponse(HTTP_CONFLICT);

        JSONObject set = createMacHostSet(mac, vlan);
        JSONObject conf = new JSONObject();
        conf.put(acl, set);

        for (String method : new String[] { HTTP_POST, HTTP_PUT }) {
            getJsonResult(mapUri2, method, conf.toString());
            assertResponse(HTTP_CONFLICT);

            uri = createRelativeURI(mapUri2, acl);
            getJsonResult(uri, method, set.toString());
            assertResponse(HTTP_CONFLICT);
        }

        if (mac == null) {
            continue;
        }

        // Try to register duplicate MAC address.
        uri = createRelativeURI(mapUri, acl, mac, "1000");
        getJsonResult(uri, HTTP_PUT);
        assertResponse(HTTP_CONFLICT);

        set = createMacHostSet(mac, "1000");
        conf = new JSONObject();
        conf.put(acl, set);

        String method = HTTP_POST;
        getJsonResult(mapUri, method, conf.toString());
        assertResponse(HTTP_CONFLICT);

        uri = createRelativeURI(mapUri, acl);
        getJsonResult(uri, method, set.toString());
        assertResponse(HTTP_CONFLICT);
    }

    // Duplicate MAC address in allow set.
    String acl = "allow";
    String mac = "00:11:22:33:55:88";
    JSONObject set = createMacHostSet(mac, "1000", mac, "1001");
    for (String method : new String[] { HTTP_POST, HTTP_PUT }) {
        JSONObject conf = new JSONObject();
        conf.put(acl, set);

        getJsonResult(mapUri, method, conf.toString());
        assertResponse(HTTP_BAD_REQUEST);

        String uri = createRelativeURI(mapUri, acl);
        getJsonResult(uri, method, set.toString());
        assertResponse(HTTP_BAD_REQUEST);
    }

    // Configuration should not be affected.
    assertMacMapping(mapUri, configExpected);

    // Remove 2 hosts from both list.
    for (int i = 0; i < 4; i++) {
        allowedHosts.removeFirst();
        deniedHosts.removeFirst();
    }

    config = createMacMapConfig(allowedHosts, deniedHosts);
    getJsonResult(mapUri, HTTP_PUT, config.toString());
    assertResponse(HTTP_OK);

    configExpected = completeMacMapConfig(config);
    assertMacMapping(mapUri, configExpected);

    for (String acl1 : acls) {
        LinkedList<String> hostList = (acl1.equals("allow")) ? allowedHosts : deniedHosts;

        // Remove 2 hosts by specifying the list.
        String mac1 = hostList.removeFirst();
        String vlan1 = hostList.removeFirst();
        String mac2 = hostList.removeFirst();
        String vlan2 = hostList.removeFirst();
        JSONObject set1 = createMacHostSet(mac1, vlan1, mac2, vlan2);

        String uri = createRelativeURI(mapUri, acl1 + remove);
        getJsonResult(uri, HTTP_POST, set1.toString());
        assertResponse(HTTP_OK);
        assertMacMapping(mapUri, allowedHosts, deniedHosts);
    }

    // Remove 2 hosts from both lists.
    config = new JSONObject();
    for (String acl1 : acls) {
        LinkedList<String> hostList = (acl1.equals("allow")) ? allowedHosts : deniedHosts;
        String mac1 = hostList.removeFirst();
        String vlan1 = hostList.removeFirst();
        String mac2 = hostList.removeFirst();
        String vlan2 = hostList.removeFirst();
        JSONObject set1 = createMacHostSet(mac1, vlan1, mac2, vlan2);
        config.put(acl1, set1);
    }
    getJsonResult(mapUri + remove, HTTP_POST, config.toString());
    assertResponse(HTTP_OK);
    assertMacMapping(mapUri, allowedHosts, deniedHosts);

    // Remove 3 hosts by DELETE.
    for (String acl1 : acls) {
        LinkedList<String> hostList = (acl1.equals("allow")) ? allowedHosts : deniedHosts;

        for (int i = 0; i < 3; i++) {
            String m = hostList.removeFirst();
            String v = hostList.removeFirst();
            String uri = createRelativeURI(mapUri, acl1, (m == null) ? "ANY" : m, (v == null) ? "0" : v);
            getJsonResult(uri, HTTP_DELETE);
            assertResponse(HTTP_OK);
        }
    }
    assertMacMapping(mapUri, allowedHosts, deniedHosts);

    // Remove 3 hosts, and add 4 hosts by PUT.
    byte[] base = { (byte) 0xa0, (byte) 0xa1, (byte) 0xa2, (byte) 0x00, (byte) 0xa4, (byte) 0xa5, };
    for (String acl1 : acls) {
        LinkedList<String> hostList = (acl1.equals("allow")) ? allowedHosts : deniedHosts;
        for (int i = 0; i < 6; i++) {
            hostList.removeFirst();
        }

        for (int i = 0; i < 4; i++) {
            base[3] = (byte) i;
            hostList.add(ByteUtils.toHexString(base));
            hostList.add(String.valueOf(i + 500));
        }
    }

    config = createMacMapConfig(allowedHosts, deniedHosts);
    configExpected = completeMacMapConfig(config);
    getJsonResult(mapUri, HTTP_PUT, config.toString());
    assertResponse(HTTP_OK);
    assertMacMapping(mapUri, allowedHosts, deniedHosts);

    for (String acl1 : acls) {
        LinkedList<String> hostList = (acl1.equals("allow")) ? allowedHosts : deniedHosts;
        for (int i = 0; i < 6; i++) {
            hostList.removeFirst();
        }

        for (int i = 20; i < 24; i++) {
            base[3] = (byte) i;
            hostList.add(ByteUtils.toHexString(base));
            hostList.add(String.valueOf(i + 500));
        }

        JSONObject set1 = createMacHostSet(hostList);
        getJsonResult(createRelativeURI(mapUri, acl1), HTTP_PUT, set1.toString());
        assertResponse(HTTP_OK);
        assertMacMapping(mapUri, allowedHosts, deniedHosts);
    }

    // Remove MAC mapping by specifying host list.
    LinkedList<String> saveAllowed = new LinkedList<String>(allowedHosts);
    LinkedList<String> saveDenied = new LinkedList<String>(deniedHosts);
    for (int i = 0; i < acls.length; i++) {
        String acl1 = acls[i];
        LinkedList<String> hostList = (acl1.equals("allow")) ? allowedHosts : deniedHosts;
        hostList.clear();

        String uri = createRelativeURI(mapUri, acl1);
        getJsonResult(uri, HTTP_DELETE);
        assertResponse(HTTP_OK);

        if (i == acls.length - 1) {
            assertNoMacMapping(mapUri);
        } else {
            assertMacMapping(mapUri, allowedHosts, deniedHosts);
        }
    }

    // Install the same MAC mapping to another vBridge.
    config = createMacMapConfig(saveAllowed, saveDenied);
    configExpected = completeMacMapConfig(config);
    getJsonResult(mapUri2, HTTP_PUT, config.toString());
    assertResponse(HTTP_CREATED);
    assertMacMapping(mapUri2, configExpected);

    getJsonResult(mapUri2, HTTP_DELETE);
    assertResponse(HTTP_OK);
    assertNoMacMapping(mapUri2);

    // Create MAC mapping by installing a host to the specific URI.
    mac = "00:11:22:33:44:55";
    String vlan = "4095";
    JSONObject hostSet = createMacHostSet(mac, vlan);
    List<String> empty = new LinkedList<String>();

    for (String acl1 : acls) {
        JSONObject set1;
        if (acl1.equals("allow")) {
            set1 = createMacHostSet(saveAllowed);
            config = createMacMapConfig(saveAllowed, empty);
        } else {
            set1 = createMacHostSet(saveDenied);
            config = createMacMapConfig(empty, saveDenied);
        }

        configExpected = completeMacMapConfig(config);
        String uri = createRelativeURI(mapUri2, acl1);
        for (String method : new String[] { HTTP_PUT, HTTP_POST }) {
            getJsonResult(uri + qparam, method, set1.toString());
            assertResponse(HTTP_CREATED);
            Assert.assertEquals(uri, httpLocation);
            assertMacMapping(mapUri2, configExpected);

            getJsonResult(uri, HTTP_DELETE);
            assertResponse(HTTP_OK);
            assertNoMacMapping(mapUri2);
        }

        config = new JSONObject();
        config.put(acl1, hostSet);
        String hostUri = createRelativeURI(uri, mac, vlan);
        getJsonResult(hostUri + qparam, HTTP_PUT);
        assertResponse(HTTP_CREATED);
        Assert.assertEquals(hostUri, httpLocation);
        assertMacMapping(mapUri2, config);

        getJsonResult(hostUri, HTTP_DELETE);
        assertResponse(HTTP_OK);
        assertNoMacMapping(mapUri2);
    }
}

From source file:edu.mit.mobile.android.locast.sync.SyncEngine.java

/**
 * @param toSync//from ww  w  .  ja  va  2s  .c  o m
 * @param account
 * @param extras
 * @param provider
 * @param syncResult
 * @return true if the item was sync'd successfully. Soft errors will cause this to return
 *         false.
 * @throws RemoteException
 * @throws SyncException
 * @throws JSONException
 * @throws IOException
 * @throws NetworkProtocolException
 * @throws NoPublicPath
 * @throws OperationApplicationException
 * @throws InterruptedException
 */
public boolean sync(Uri toSync, Account account, Bundle extras, ContentProviderClient provider,
        SyncResult syncResult) throws RemoteException, SyncException, JSONException, IOException,
        NetworkProtocolException, NoPublicPath, OperationApplicationException, InterruptedException {

    String pubPath = null;

    //
    // Handle http or https uris separately. These require the
    // destination uri.
    //
    if ("http".equals(toSync.getScheme()) || "https".equals(toSync.getScheme())) {
        pubPath = toSync.toString();

        if (!extras.containsKey(EXTRA_DESTINATION_URI)) {
            throw new IllegalArgumentException("missing EXTRA_DESTINATION_URI when syncing HTTP URIs");
        }
        toSync = Uri.parse(extras.getString(EXTRA_DESTINATION_URI));
    }

    final String type = provider.getType(toSync);
    final boolean isDir = type.startsWith(CONTENT_TYPE_PREFIX_DIR);

    final boolean manualSync = extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false);

    // skip any items already sync'd
    if (!manualSync && mLastUpdated.isUpdatedRecently(toSync)) {
        if (DEBUG) {
            Log.d(TAG, "not syncing " + toSync + " as it's been updated recently");
        }
        syncResult.stats.numSkippedEntries++;
        return false;
    }

    // the sync map will convert the json data to ContentValues
    final SyncMap syncMap = MediaProvider.getSyncMap(provider, toSync);

    final Uri toSyncWithoutQuerystring = toSync.buildUpon().query(null).build();

    final HashMap<String, SyncStatus> syncStatuses = new HashMap<String, SyncEngine.SyncStatus>();
    final ArrayList<ContentProviderOperation> cpo = new ArrayList<ContentProviderOperation>();
    final LinkedList<String> cpoPubUris = new LinkedList<String>();

    //
    // first things first, upload any content that needs to be
    // uploaded.
    //

    try {
        uploadUnpublished(toSync, account, provider, syncMap, syncStatuses, syncResult);

        if (Thread.interrupted()) {
            throw new InterruptedException();
        }

        // this should ensure that all items have a pubPath when we
        // query it below.

        if (pubPath == null) {
            // we should avoid calling this too much as it
            // can be expensive
            pubPath = MediaProvider.getPublicPath(mContext, toSync);
        }
    } catch (final NoPublicPath e) {
        // TODO this is a special case and this is probably not the best place to handle this.
        // Ideally, this should be done in such a way as to reduce any extra DB queries -
        // perhaps by doing a join with the parent.
        if (syncMap.isFlagSet(SyncMap.FLAG_PARENT_MUST_SYNC_FIRST)) {
            if (DEBUG) {
                Log.d(TAG, "skipping " + toSync + " whose parent hasn't been sync'd first");
            }
            syncResult.stats.numSkippedEntries++;
            return false;
        }

        // if it's an item, we can handle it.
        if (isDir) {
            throw e;
        }
    }

    if (pubPath == null) {

        // this should have been updated already by the initial
        // upload, so something must be wrong
        throw new SyncException("never got a public path for " + toSync);
    }

    if (DEBUG) {
        Log.d(TAG, "sync(toSync=" + toSync + ", account=" + account + ", extras=" + extras + ", manualSync="
                + manualSync + ",...)");
        Log.d(TAG, "pubPath: " + pubPath);
    }

    final long request_time = System.currentTimeMillis();

    HttpResponse hr = mNetworkClient.get(pubPath);

    final long response_time = System.currentTimeMillis();

    // the time compensation below allows a time-based synchronization to function even if the
    // local clock is entirely wrong. The server's time is extracted using the Date header and
    // all are compared relative to the respective clock reference. Any data that's stored on
    // the mobile should be stored relative to the local clock and the server will respect the
    // same.
    long serverTime;

    try {
        serverTime = getServerTime(hr);
    } catch (final DateParseException e) {
        Log.w(TAG, "could not retrieve date from server. Using local time, which may be incorrect.", e);
        serverTime = System.currentTimeMillis();
    }

    // TODO check out
    // http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html
    final long response_delay = response_time - request_time;
    if (DEBUG) {
        Log.d(TAG, "request took " + response_delay + "ms");
    }
    final long localTime = request_time;

    // add this to the server time to get the local time
    final long localOffset = (localTime - serverTime);

    if (Math.abs(localOffset) > 30 * 60 * 1000) {
        Log.w(TAG, "local clock is off by " + localOffset + "ms");
    }

    if (Thread.interrupted()) {
        throw new InterruptedException();
    }

    final HttpEntity ent = hr.getEntity();

    String selection;
    String selectionInverse;
    String[] selectionArgs;

    if (isDir) {

        final JSONArray ja = new JSONArray(StreamUtils.inputStreamToString(ent.getContent()));
        ent.consumeContent();

        final int len = ja.length();
        selectionArgs = new String[len];

        // build the query to see which items are already in the
        // database
        final StringBuilder sb = new StringBuilder();

        sb.append("(");

        for (int i = 0; i < len; i++) {
            if (Thread.interrupted()) {
                throw new InterruptedException();
            }

            final SyncStatus syncStatus = loadItemFromJsonObject(ja.getJSONObject(i), syncMap, serverTime);

            syncStatuses.put(syncStatus.remote, syncStatus);

            selectionArgs[i] = syncStatus.remote;

            // add in a placeholder for the query
            sb.append('?');
            if (i != (len - 1)) {
                sb.append(',');
            }

        }
        sb.append(")");

        final String placeholders = sb.toString();
        selection = JsonSyncableItem._PUBLIC_URI + " IN " + placeholders;
        selectionInverse = JsonSyncableItem._PUBLIC_URI + " NOT IN " + placeholders;
    } else {

        final JSONObject jo = new JSONObject(StreamUtils.inputStreamToString(ent.getContent()));
        ent.consumeContent();
        final SyncStatus syncStatus = loadItemFromJsonObject(jo, syncMap, serverTime);

        syncStatuses.put(syncStatus.remote, syncStatus);

        selection = JsonSyncableItem._PUBLIC_URI + "=?";
        selectionInverse = JsonSyncableItem._PUBLIC_URI + "!=?";
        selectionArgs = new String[] { syncStatus.remote };
    }

    // first check without the querystring. This will ensure that we
    // properly mark things that we already have in the database.
    final Cursor check = provider.query(toSyncWithoutQuerystring, SYNC_PROJECTION, selection, selectionArgs,
            null);

    // these items are on both sides
    try {
        final int pubUriCol = check.getColumnIndex(JsonSyncableItem._PUBLIC_URI);
        final int idCol = check.getColumnIndex(JsonSyncableItem._ID);

        // All the items in this cursor should be found on both
        // the client and the server.
        for (check.moveToFirst(); !check.isAfterLast(); check.moveToNext()) {
            if (Thread.interrupted()) {
                throw new InterruptedException();
            }

            final long id = check.getLong(idCol);
            final Uri localUri = ContentUris.withAppendedId(toSync, id);

            final String pubUri = check.getString(pubUriCol);

            final SyncStatus itemStatus = syncStatuses.get(pubUri);

            itemStatus.state = SyncState.BOTH_UNKNOWN;

            itemStatus.local = localUri;

            // make the status searchable by both remote and
            // local uri
            syncStatuses.put(localUri.toString(), itemStatus);
        }
    } finally {
        check.close();
    }

    Cursor c = provider.query(toSync, SYNC_PROJECTION, selection, selectionArgs, null);

    // these items are on both sides
    try {
        final int pubUriCol = c.getColumnIndex(JsonSyncableItem._PUBLIC_URI);
        final int localModifiedCol = c.getColumnIndex(JsonSyncableItem._MODIFIED_DATE);
        final int serverModifiedCol = c.getColumnIndex(JsonSyncableItem._SERVER_MODIFIED_DATE);
        final int idCol = c.getColumnIndex(JsonSyncableItem._ID);

        // All the items in this cursor should be found on both
        // the client and the server.
        for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
            if (Thread.interrupted()) {
                throw new InterruptedException();
            }

            final long id = c.getLong(idCol);
            final Uri localUri = ContentUris.withAppendedId(toSync, id);

            final String pubUri = c.getString(pubUriCol);

            final SyncStatus itemStatus = syncStatuses.get(pubUri);

            if (itemStatus.state == SyncState.ALREADY_UP_TO_DATE
                    || itemStatus.state == SyncState.NOW_UP_TO_DATE) {
                if (DEBUG) {
                    Log.d(TAG, localUri + "(" + pubUri + ")" + " is already up to date.");
                }
                continue;
            }

            itemStatus.local = localUri;

            // make the status searchable by both remote and local uri
            syncStatuses.put(localUri.toString(), itemStatus);

            // last modified as stored in the DB, in phone time
            final long itemLocalModified = c.getLong(localModifiedCol);

            // last modified as stored in the DB, in server time
            final long itemServerModified = c.getLong(serverModifiedCol);
            final long localAge = localTime - itemLocalModified;

            final long remoteAge = serverTime - itemStatus.remoteModifiedTime;

            final long ageDifference = Math.abs(localAge - remoteAge);

            // up to date, as far remote -> local goes
            if (itemServerModified == itemStatus.remoteModifiedTime) {
                itemStatus.state = SyncState.ALREADY_UP_TO_DATE;
                if (DEBUG) {
                    Log.d(TAG, pubUri + " is up to date.");
                }

                // need to download
            } else if (localAge > remoteAge) {
                if (DEBUG) {
                    final long serverModified = itemStatus.remoteModifiedTime;

                    Log.d(TAG,
                            pubUri + " : local is " + ageDifference + "ms older ("
                                    + android.text.format.DateUtils.formatDateTime(mContext, itemLocalModified,
                                            FORMAT_ARGS_DEBUG)
                                    + ") than remote (" + android.text.format.DateUtils.formatDateTime(mContext,
                                            serverModified, FORMAT_ARGS_DEBUG)
                                    + "); updating local copy...");
                }

                itemStatus.state = SyncState.REMOTE_DIRTY;

                final ContentProviderOperation.Builder b = ContentProviderOperation.newUpdate(localUri);

                // update this so it's in the local timescale
                correctServerOffset(itemStatus.remoteCVs, JsonSyncableItem._CREATED_DATE,
                        JsonSyncableItem._CREATED_DATE, localOffset);
                correctServerOffset(itemStatus.remoteCVs, JsonSyncableItem._SERVER_MODIFIED_DATE,
                        JsonSyncableItem._MODIFIED_DATE, localOffset);

                b.withValues(itemStatus.remoteCVs);
                b.withExpectedCount(1);

                cpo.add(b.build());
                cpoPubUris.add(pubUri);

                syncResult.stats.numUpdates++;

                // need to upload
            } else if (localAge < remoteAge) {
                if (DEBUG) {
                    final long serverModified = itemStatus.remoteModifiedTime;

                    Log.d(TAG,
                            pubUri + " : local is " + ageDifference + "ms newer ("
                                    + android.text.format.DateUtils.formatDateTime(mContext, itemLocalModified,
                                            FORMAT_ARGS_DEBUG)
                                    + ") than remote (" + android.text.format.DateUtils.formatDateTime(mContext,
                                            serverModified, FORMAT_ARGS_DEBUG)
                                    + "); publishing to server...");
                }
                itemStatus.state = SyncState.LOCAL_DIRTY;

                mNetworkClient.putJson(pubPath, JsonSyncableItem.toJSON(mContext, localUri, c, syncMap));
            }

            mLastUpdated.markUpdated(localUri);

            syncResult.stats.numEntries++;
        } // end for
    } finally {

        c.close();
    }

    /*
     * Apply updates in bulk
     */
    if (cpo.size() > 0) {
        if (DEBUG) {
            Log.d(TAG, "applying " + cpo.size() + " bulk updates...");
        }

        final ContentProviderResult[] r = provider.applyBatch(cpo);
        if (DEBUG) {
            Log.d(TAG, "Done applying updates. Running postSync handler...");
        }

        for (int i = 0; i < r.length; i++) {
            final ContentProviderResult res = r[i];
            final SyncStatus ss = syncStatuses.get(cpoPubUris.get(i));
            if (ss == null) {
                Log.e(TAG, "can't get sync status for " + res.uri);
                continue;
            }
            syncMap.onPostSyncItem(mContext, account, ss.local, ss.remoteJson,
                    res.count != null ? res.count == 1 : true);

            ss.state = SyncState.NOW_UP_TO_DATE;
        }

        if (DEBUG) {
            Log.d(TAG, "done running postSync handler.");
        }

        cpo.clear();
        cpoPubUris.clear();
    }

    if (Thread.interrupted()) {
        throw new InterruptedException();
    }

    /*
     * Look through the SyncState.state values and find ones that need to be stored.
     */

    for (final Map.Entry<String, SyncStatus> entry : syncStatuses.entrySet()) {
        if (Thread.interrupted()) {
            throw new InterruptedException();
        }

        final String pubUri = entry.getKey();
        final SyncStatus status = entry.getValue();
        if (status.state == SyncState.REMOTE_ONLY) {
            if (DEBUG) {
                Log.d(TAG, pubUri + " is not yet stored locally, adding...");
            }

            // update this so it's in the local timescale
            correctServerOffset(status.remoteCVs, JsonSyncableItem._CREATED_DATE,
                    JsonSyncableItem._CREATED_DATE, localOffset);
            correctServerOffset(status.remoteCVs, JsonSyncableItem._SERVER_MODIFIED_DATE,
                    JsonSyncableItem._MODIFIED_DATE, localOffset);

            final ContentProviderOperation.Builder b = ContentProviderOperation.newInsert(toSync);
            b.withValues(status.remoteCVs);

            cpo.add(b.build());
            cpoPubUris.add(pubUri);
            syncResult.stats.numInserts++;

        }
    }

    /*
     * Execute the content provider operations in bulk.
     */
    if (cpo.size() > 0) {
        if (DEBUG) {
            Log.d(TAG, "bulk inserting " + cpo.size() + " items...");
        }
        final ContentProviderResult[] r = provider.applyBatch(cpo);
        if (DEBUG) {
            Log.d(TAG, "applyBatch completed. Processing results...");
        }

        int successful = 0;
        for (int i = 0; i < r.length; i++) {
            final ContentProviderResult res = r[i];
            if (res.uri == null) {
                syncResult.stats.numSkippedEntries++;
                Log.e(TAG, "result from content provider bulk operation returned null");
                continue;
            }
            final String pubUri = cpoPubUris.get(i);
            final SyncStatus ss = syncStatuses.get(pubUri);

            if (ss == null) {
                syncResult.stats.numSkippedEntries++;
                Log.e(TAG, "could not find sync status for " + cpoPubUris.get(i));
                continue;
            }

            ss.local = res.uri;
            if (DEBUG) {
                Log.d(TAG, "onPostSyncItem(" + res.uri + ", ...); pubUri: " + pubUri);
            }

            syncMap.onPostSyncItem(mContext, account, res.uri, ss.remoteJson,
                    res.count != null ? res.count == 1 : true);

            ss.state = SyncState.NOW_UP_TO_DATE;
            successful++;
        }
        if (DEBUG) {
            Log.d(TAG, successful + " batch inserts successfully applied.");
        }
    } else {
        if (DEBUG) {
            Log.d(TAG, "no updates to perform.");
        }
    }

    /**
     * Look through all the items that we didn't already find on the server side, but which
     * still have a public uri. They should be checked to make sure they're not deleted.
     */
    c = provider.query(toSync, SYNC_PROJECTION,
            ProviderUtils.addExtraWhere(selectionInverse, JsonSyncableItem._PUBLIC_URI + " NOT NULL"),
            selectionArgs, null);

    try {
        final int idCol = c.getColumnIndex(JsonSyncableItem._ID);
        final int pubUriCol = c.getColumnIndex(JsonSyncableItem._PUBLIC_URI);

        cpo.clear();

        for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
            final String pubUri = c.getString(pubUriCol);
            SyncStatus ss = syncStatuses.get(pubUri);

            final Uri item = isDir ? ContentUris.withAppendedId(toSyncWithoutQuerystring, c.getLong(idCol))
                    : toSync;

            if (ss == null) {
                ss = syncStatuses.get(item.toString());
            }

            if (DEBUG) {
                Log.d(TAG, item + " was not found in the main list of items on the server (" + pubPath
                        + "), but appears to be a child of " + toSync);

                if (ss != null) {
                    Log.d(TAG, "found sync status for " + item + ": " + ss);
                }
            }

            if (ss != null) {
                switch (ss.state) {
                case ALREADY_UP_TO_DATE:
                case NOW_UP_TO_DATE:
                    if (DEBUG) {
                        Log.d(TAG, item + " is already up to date. No need to see if it was deleted.");
                    }
                    continue;

                case BOTH_UNKNOWN:
                    if (DEBUG) {
                        Log.d(TAG,
                                item + " was found on both sides, but has an unknown sync status. Skipping...");
                    }
                    continue;

                default:

                    Log.w(TAG, "got an unexpected state for " + item + ": " + ss);
                }

            } else {
                ss = new SyncStatus(pubUri, SyncState.LOCAL_ONLY);
                ss.local = item;

                hr = mNetworkClient.head(pubUri);

                switch (hr.getStatusLine().getStatusCode()) {
                case 200:
                    if (DEBUG) {
                        Log.d(TAG, "HEAD " + pubUri + " returned 200");
                    }
                    ss.state = SyncState.BOTH_UNKNOWN;
                    break;

                case 404:
                    if (DEBUG) {
                        Log.d(TAG, "HEAD " + pubUri + " returned 404. Deleting locally...");
                    }
                    ss.state = SyncState.DELETED_REMOTELY;
                    final ContentProviderOperation deleteOp = ContentProviderOperation
                            .newDelete(ContentUris.withAppendedId(toSyncWithoutQuerystring, c.getLong(idCol)))
                            .build();
                    cpo.add(deleteOp);

                    break;

                default:
                    syncResult.stats.numIoExceptions++;
                    Log.w(TAG, "HEAD " + pubUri + " got unhandled result: " + hr.getStatusLine());
                }
            }
            syncStatuses.put(pubUri, ss);
        } // for cursor

        if (cpo.size() > 0) {
            final ContentProviderResult[] results = provider.applyBatch(cpo);

            for (final ContentProviderResult result : results) {
                if (result.count != 1) {
                    throw new SyncException("Error deleting item");
                }
            }
        }

    } finally {
        c.close();
    }

    syncStatuses.clear();

    mLastUpdated.markUpdated(toSync);

    return true;
}

From source file:edu.ku.brc.specify.tasks.subpane.qb.QueryBldrPane.java

/**
 * @param rootTable/*from  w ww . ja  va  2 s. c  om*/
 * @param distinct
 * @param qfps
 * @param tblTree
 * @param keysToRetrieve
 * @return HQLSpecs for the current fields and settings.
 */
public static HQLSpecs buildHQL(final TableQRI rootTable, final boolean distinct,
        final Vector<QueryFieldPanel> qfps, final TableTree tblTree, final RecordSetIFace keysToRetrieve,
        final boolean searchSynonymy, final boolean isSchemaExport, final Timestamp lastExportTime,
        final boolean disjunct) throws ParseException {
    if (qfps.size() == 0)
        return null;

    if (keysToRetrieve != null && keysToRetrieve.getNumItems() == 0)
        return null;

    StringBuilder fieldsStr = new StringBuilder();
    Vector<BaseQRI> list = new Vector<BaseQRI>();
    StringBuilder criteriaStr = new StringBuilder();
    StringBuilder orderStr = new StringBuilder();
    LinkedList<SortElement> sortElements = new LinkedList<SortElement>();
    boolean postSortPresent = false;
    boolean debug = false;
    ProcessNode root = new ProcessNode();
    int fldPosition = distinct ? 0 : 1;

    for (QueryFieldPanel qfi : qfps) {
        if (qfi.getFieldQRI() == null) {
            continue;
        }

        qfi.updateQueryField();

        if (qfi.isForDisplay()) {
            fldPosition++;
        }

        if (debug) {
            log.debug("\nNode: " + qfi.getFieldName());
        }

        SortElement orderSpec = qfi.getOrderSpec(distinct ? fldPosition - 1 : fldPosition - 2);
        if (orderSpec != null) {
            boolean isPostSortSpec = qfi.getFieldQRI() instanceof TreeLevelQRI
                    || qfi.getFieldQRI() instanceof RelQRI;
            //dis regard post sorts that may have been saved before
            //fix for bug #9407
            if (!isSchemaExport) {
                postSortPresent |= isPostSortSpec;
            }
            if (!isPostSortSpec || !isSchemaExport) {
                sortElements.add(orderSpec);
            }
        }

        // Create a Stack (list) of parent from
        // the current node up to the top
        // basically we are creating a path of nodes
        // to determine if we need to create a new node in the tree
        list.clear();
        FieldQRI pqri = qfi.getFieldQRI();
        TableTree parent = pqri.getTableTree();
        if (qfi.isForDisplay() || qfi.hasCriteria() || orderSpec != null || pqri instanceof RelQRI) {
            boolean addToList = true;
            if (pqri instanceof RelQRI) {
                RelQRI relQRI = (RelQRI) pqri;
                RelationshipType relType = relQRI.getRelationshipInfo().getType();

                // XXX Formatter.getSingleField() checks for ZeroOrOne and
                // OneToOne rels.

                if (!relType.equals(RelationshipType.ManyToOne)
                        && !relType.equals(RelationshipType.ManyToMany)/*
                                                                       * treat
                                                                       * manytomany
                                                                       * as
                                                                       * onetomany
                                                                       */) // Maybe
                                                                                                                            // need
                                                                                                                            // to
                                                                                                                            // consider
                                                                                                                            // some
                                                                                                                            // types
                                                                                                                            // of
                                                                                                                            // OneToOne
                                                                                                                            // also?????????
                {
                    parent = parent.getParent();
                    if (isSchemaExport && lastExportTime != null) {
                        addToList = true;
                    } else {
                        // parent will initially point to the related table
                        // and don't need to add related table unless it has
                        // children displayed/queried,
                        addToList = false;
                    }
                } else {
                    DataObjDataFieldFormatIFace formatter = relQRI.getDataObjFormatter(qfi.getFormatName());
                    if (formatter != null) {
                        boolean isSingleSimpleFormat = formatter.getSingleField() != null
                                && formatter.getFields()[0].getSep() == null;
                        addToList = isSingleSimpleFormat || (isSchemaExport && lastExportTime != null);
                    } else {
                        addToList = false;
                    }
                }
            }
            if (addToList) {
                list.insertElementAt(pqri, 0);
            }
            while (parent != tblTree) {
                list.insertElementAt(parent.getTableQRI(), 0);
                parent = parent.getParent();
            }

            if (debug) {
                log.debug("Path From Top Down:");
                for (BaseQRI qri : list) {
                    log.debug("  " + qri.getTitle());
                }
            }

            // Now walk the stack top (the top most parent)
            // down and if the path form the top down doesn't
            // exist then add a new node
            ProcessNode parentNode = root;
            int q = 0;
            for (BaseQRI qri : list) {
                if (debug) {
                    log.debug("ProcessNode[" + qri.getTitle() + "]");
                }
                q++;
                if (!parentNode.contains(qri) && (qri instanceof TableQRI || q == list.size())) {
                    ProcessNode newNode = new ProcessNode(qri);
                    parentNode.getKids().add(newNode);
                    if (debug) {
                        log.debug("Adding new node[" + newNode.getQri().getTitle() + "] to Node["
                                + (parentNode.getQri() == null ? "root" : parentNode.getQri().getTitle())
                                + "]");
                    }
                    parentNode = newNode;
                } else {
                    for (ProcessNode kidNode : parentNode.getKids()) {
                        if (kidNode.getQri().equals(qri)) {
                            parentNode = kidNode;
                            break;
                        }
                    }
                }
            }

            if (debug) {
                log.debug("Current Tree:");
                printTree(root, 0);
            }
        }
    }

    if (debug) {
        printTree(root, 0);
    }

    StringBuilder fromStr = new StringBuilder();
    TableAbbreviator tableAbbreviator = new TableAbbreviator();
    List<Pair<DBTableInfo, String>> fromTbls = new LinkedList<Pair<DBTableInfo, String>>();
    boolean hqlHasSynJoins = processTree(root, fromStr, fromTbls, 0, tableAbbreviator, tblTree, qfps,
            searchSynonymy, isSchemaExport, lastExportTime);

    StringBuilder sqlStr = new StringBuilder();
    sqlStr.append("select ");
    //if (distinct /*|| hqlHasSynJoins*/)
    {
        sqlStr.append("distinct ");
    }
    if (!distinct) {
        fieldsStr.append(tableAbbreviator.getAbbreviation(rootTable.getTableTree()));
        fieldsStr.append(".");
        fieldsStr.append(rootTable.getTableInfo().getIdFieldName());
    }

    List<Pair<String, Object>> paramsToSet = new LinkedList<Pair<String, Object>>();
    boolean visibleFldExists = false;
    for (QueryFieldPanel qfi : qfps) {
        if (qfi.getFieldQRI() == null) {
            continue;
        }

        if (qfi.isForDisplay()) {
            visibleFldExists = true;
            String fldSpec = qfi.getFieldQRI().getSQLFldSpec(tableAbbreviator, false, isSchemaExport,
                    qfi.getFormatName());
            if (StringUtils.isNotEmpty(fldSpec)) {
                if (fieldsStr.length() > 0) {
                    fieldsStr.append(", ");
                }
                fieldsStr.append(fldSpec);
            }
        }
        if (keysToRetrieve == null || qfi.isEnforced()) {
            String criteria = qfi.getCriteriaFormula(tableAbbreviator, paramsToSet);
            boolean isDisplayOnly = StringUtils.isEmpty(criteria);
            if (!isDisplayOnly) {
                if (criteria.equals("2+2=2") && qfi.isNegated()) {
                    criteria = "";
                }
                if (criteria.length() > 0 && hqlHasSynJoins && isSynSearchable(qfi.getFieldQRI())
                        && !qfi.isEmptyCriterion()) {
                    criteria = adjustForSynSearch(
                            tableAbbreviator.getAbbreviation(qfi.getFieldQRI().getTable().getTableTree()),
                            criteria, qfi.isNegated());
                }
                if (!isDisplayOnly && criteriaStr.length() > 0 && criteria.length() > 0) {
                    criteriaStr.append(disjunct ? " OR " : " AND ");
                }
                criteriaStr.append(criteria);
            }
        }
    }
    if (!visibleFldExists) {
        throw new ParseException(getResourceString("QueryBldrPane.NoVisibleColumns"), -1);
    }

    sqlStr.append(fieldsStr);

    sqlStr.append(" from ");
    sqlStr.append(fromStr);

    if (keysToRetrieve != null) {
        if (!StringUtils.isEmpty(criteriaStr.toString())) {
            criteriaStr.append(" and ");
        }
        criteriaStr.append("(");
        criteriaStr.append(tableAbbreviator.getAbbreviation(rootTable.getTableTree()) + "."
                + rootTable.getTableInfo().getIdFieldName() + " in(");
        boolean comma = false;
        int maxInClauseLen = 2500;
        int inClauseLen = 0;
        for (RecordSetItemIFace item : keysToRetrieve.getOrderedItems()) {
            if (inClauseLen == maxInClauseLen) {
                criteriaStr.append(") or ");
                criteriaStr.append(tableAbbreviator.getAbbreviation(rootTable.getTableTree()) + "."
                        + rootTable.getTableInfo().getIdFieldName() + " in(");
                inClauseLen = 0;
            } else if (comma) {
                criteriaStr.append(",");
            } else {
                comma = true;
            }
            criteriaStr.append(item.getRecordId());
            inClauseLen++;
        }
        criteriaStr.append("))");
    } else {
        //Assuming that this not necessary when keysToRetrieve is non-null because
        //the keys will already been filtered properly. (???)

        // Add extra where's for system fields for root table only, see notes below at end of for block
        boolean isRootTbl = true;
        for (Pair<DBTableInfo, String> fromTbl : fromTbls) {
            String specialColumnWhere = null;
            if (fromTbl.getFirst().getTableId() == Attachment.getClassTableId()) {
                String prefix = fromTbl.getSecond() + ".";
                specialColumnWhere = "((" + prefix + "scopeType = 0 and " + prefix + "scopeID = "
                        + AppContextMgr.getInstance()
                                .getClassObject(edu.ku.brc.specify.datamodel.Collection.class).getCollectionId()
                        + ") or" + "(" + prefix + "scopeType = 1 and " + prefix + "scopeID = "
                        + AppContextMgr.getInstance().getClassObject(Discipline.class).getDisciplineId()
                        + ") or" + "(" + prefix + "scopeType = 2 and " + prefix + "scopeID = "
                        + AppContextMgr.getInstance().getClassObject(Division.class).getDivisionId() + ") or"
                        + "(" + prefix + "scopeType = 3 and " + prefix + "scopeID = "
                        + AppContextMgr.getInstance().getClassObject(Institution.class).getInstitutionId()
                        + "))";
            } else {
                specialColumnWhere = QueryAdjusterForDomain.getInstance().getSpecialColumns(fromTbl.getFirst(),
                        true, !isRootTbl && true/* XXX should only use left join when necessary */,
                        fromTbl.getSecond());
            }
            isRootTbl = false;
            if (StringUtils.isNotEmpty(specialColumnWhere)) {
                if (criteriaStr.length() > 0) {
                    criteriaStr.append(" AND ");
                }
                criteriaStr.append(specialColumnWhere);
            }
            //Actually, assuming data is valid, it should only be necessary to add the Adjustments for the root table?
            //XXX if this works, fix this loop. Also, join parameter code in getSpecialColumns will probably be irrelevant.
            break;
        }
        //...done adding system whereses

        //get only records modified/added since last export of the schema...
        if (isSchemaExport && lastExportTime != null) {
            if (criteriaStr.length() > 0) {
                criteriaStr.append(" AND (");
            }
            String timestampParam = "spparam" + paramsToSet.size();
            paramsToSet.add(new Pair<String, Object>(timestampParam, lastExportTime));
            criteriaStr.append(getTimestampWhere(fromTbls, timestampParam, lastExportTime));
            criteriaStr.append(") ");
        }
    }

    if (criteriaStr.length() > 0) {
        sqlStr.append(" where ");
        sqlStr.append(criteriaStr);
    }

    if (sortElements.size() > 0 && !postSortPresent) {
        for (SortElement se : sortElements) {
            if (!StringUtils.isEmpty(orderStr.toString())) {
                orderStr.append(", ");
            }
            orderStr.append(distinct ? se.getColumn() + 1 : se.getColumn() + 2);
            if (se.getDirection() == SortElement.DESCENDING) {
                orderStr.append(" DESC");
            }
        }
        sortElements.clear();
    }

    if (orderStr.length() > 0) {
        sqlStr.append(" order by ");
        sqlStr.append(orderStr);
    }

    if (debug) {
        log.debug(sqlStr.toString());
        log.debug("sort:");
        for (SortElement s : sortElements) {
            log.debug("  " + s.getColumn() + " - " + s.getDirection());
        }
    }

    String result = sqlStr.toString();
    if (!checkHQL(result))
        return null;

    log.info(result);
    return new HQLSpecs(result, paramsToSet, sortElements, hqlHasSynJoins);
}