Example usage for java.util LinkedList addFirst

List of usage examples for java.util LinkedList addFirst

Introduction

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

Prototype

public void addFirst(E e) 

Source Link

Document

Inserts the specified element at the beginning of this list.

Usage

From source file:org.nuxeo.ecm.core.storage.sql.NXQLQueryMaker.java

public Query buildQuery(SQLInfo sqlInfo, Model model, Session session, String query, QueryFilter queryFilter,
        Object... params) throws StorageException {
    this.sqlInfo = sqlInfo;
    database = sqlInfo.database;/*w w  w .  j  a  va  2 s .  c o m*/
    dialect = sqlInfo.dialect;
    this.model = model;
    this.session = session;
    // transform the query according to the transformers defined by the
    // security policies
    SQLQuery sqlQuery = SQLQueryParser.parse(query);
    for (SQLQuery.Transformer transformer : queryFilter.getQueryTransformers()) {
        sqlQuery = transformer.transform(queryFilter.getPrincipal(), sqlQuery);
    }

    /*
     * Find all relevant types and keys for the criteria.
     */

    QueryAnalyzer info = new QueryAnalyzer();
    try {
        info.visitQuery(sqlQuery);
    } catch (QueryCannotMatchException e) {
        // query cannot match
        return null;
    } catch (QueryMakerException e) {
        throw new StorageException(e.getMessage(), e);
    }

    /*
     * Find all the types to take into account (all concrete types being a
     * subtype of the passed types) based on the FROM list.
     */

    Set<String> types = new HashSet<String>();
    for (String typeName : info.fromTypes) {
        if ("document".equals(typeName)) {
            typeName = "Document";
        }
        Set<String> subTypes = model.getDocumentSubTypes(typeName);
        if (subTypes == null) {
            throw new StorageException("Unknown type: " + typeName);
        }
        types.addAll(subTypes);
    }
    types.remove(model.ROOT_TYPE);

    /*
     * Restrict types based on toplevel ecm:primaryType and ecm:mixinType
     * predicates.
     */

    types.removeAll(info.typesExcluded);
    if (!info.typesAnyRequired.isEmpty()) {
        types.retainAll(info.typesAnyRequired);
    }
    if (types.isEmpty()) {
        // conflicting types requirement, query cannot match
        return null;
    }

    /*
     * Merge facet filter into mixin clauses and immutable flag.
     */

    FacetFilter facetFilter = queryFilter.getFacetFilter();
    if (facetFilter == null) {
        facetFilter = FacetFilter.ALLOW;
    }
    info.mixinsExcluded.addAll(facetFilter.excluded);
    if (info.mixinsExcluded.remove(FacetNames.IMMUTABLE)) {
        if (info.immutableClause == Boolean.TRUE) {
            // conflict on immutable condition, query cannot match
            return null;
        }
        info.immutableClause = Boolean.FALSE;
    }
    info.mixinsAllRequired.addAll(facetFilter.required);
    if (info.mixinsAllRequired.remove(FacetNames.IMMUTABLE)) {
        if (info.immutableClause == Boolean.FALSE) {
            // conflict on immutable condition, query cannot match
            return null;
        }
        info.immutableClause = Boolean.TRUE;
    }

    /*
     * Find the relevant tables to join with.
     */

    Set<String> fragmentNames = new HashSet<String>();
    for (String prop : info.props) {
        PropertyInfo propertyInfo = model.getPropertyInfo(prop);
        if (propertyInfo == null) {
            throw new StorageException("Unknown field: " + prop);
        }
        fragmentNames.add(propertyInfo.fragmentName);
    }
    fragmentNames.remove(model.hierTableName);

    // Do we need to add the versions table too?
    if (info.needsVersionsTable || info.immutableClause != null) {
        fragmentNames.add(model.VERSION_TABLE_NAME);
    }

    /*
     * Build the FROM / JOIN criteria for each select.
     */

    DocKind[] docKinds;
    if (info.proxyClause == Boolean.TRUE) {
        if (info.immutableClause == Boolean.FALSE) {
            // proxy but not immutable: query cannot match
            return null;
        }
        docKinds = new DocKind[] { DocKind.PROXY };
    } else if (info.proxyClause == Boolean.FALSE || info.immutableClause == Boolean.FALSE) {
        docKinds = new DocKind[] { DocKind.DIRECT };
    } else {
        docKinds = new DocKind[] { DocKind.DIRECT, DocKind.PROXY };
    }

    Table hier = database.getTable(model.hierTableName);

    boolean aliasColumns = docKinds.length > 1;
    Select select = null;
    String orderBy = null;
    List<String> statements = new ArrayList<String>(2);
    List<Serializable> selectParams = new LinkedList<Serializable>();
    for (DocKind docKind : docKinds) {

        // The hierarchy table, which may be an alias table.
        Table hierTable;
        // Quoted id in the hierarchy. This is the id returned by the query.
        String hierId;
        // Quoted name in the hierarchy. This is the id returned by the query.
        String hierName;
        // The hierarchy table of the data.
        Table dataHierTable;
        // Quoted id attached to the data that matches.
        String dataHierId;

        List<String> joins = new LinkedList<String>();
        LinkedList<String> leftJoins = new LinkedList<String>();
        List<Serializable> leftJoinsParams = new LinkedList<Serializable>();
        LinkedList<String> implicitJoins = new LinkedList<String>();
        List<Serializable> implicitJoinsParams = new LinkedList<Serializable>();
        List<String> whereClauses = new LinkedList<String>();
        List<Serializable> whereParams = new LinkedList<Serializable>();

        switch (docKind) {
        case DIRECT:
            hierTable = hier;
            hierId = hierTable.getColumn(model.MAIN_KEY).getFullQuotedName();
            hierName = hierTable.getColumn(model.HIER_CHILD_NAME_KEY).getFullQuotedName();
            dataHierTable = hierTable;
            dataHierId = hierId;
            joins.add(hierTable.getQuotedName());
            break;
        case PROXY:
            hierTable = new TableAlias(hier, TABLE_HIER_ALIAS);
            String hierFrom = hier.getQuotedName() + " " + hierTable.getQuotedName(); // TODO use dialect
            hierId = hierTable.getColumn(model.MAIN_KEY).getFullQuotedName();
            hierName = hierTable.getColumn(model.HIER_CHILD_NAME_KEY).getFullQuotedName();
            // joined (data)
            dataHierTable = hier;
            dataHierId = hier.getColumn(model.MAIN_KEY).getFullQuotedName();
            // proxies
            Table proxies = database.getTable(model.PROXY_TABLE_NAME);
            String proxiesid = proxies.getColumn(model.MAIN_KEY).getFullQuotedName();
            String proxiestargetid = proxies.getColumn(model.PROXY_TARGET_KEY).getFullQuotedName();
            // join all that
            joins.add(hierFrom);
            joins.add(String.format(JOIN_ON, proxies.getQuotedName(), hierId, proxiesid));
            joins.add(String.format(JOIN_ON, dataHierTable.getQuotedName(), dataHierId, proxiestargetid));
            break;
        default:
            throw new AssertionError(docKind);
        }

        // main data joins
        for (String fragmentName : fragmentNames) {
            Table table = database.getTable(fragmentName);
            // the versions table joins on the real hier table
            boolean useHier = model.VERSION_TABLE_NAME.equals(fragmentName);
            leftJoins.add(String.format(JOIN_ON, table.getQuotedName(), useHier ? hierId : dataHierId,
                    table.getColumn(model.MAIN_KEY).getFullQuotedName()));
        }

        /*
         * Filter on facets and mixin types, and create the structural WHERE
         * clauses for the type.
         */

        List<String> typeStrings = new ArrayList<String>(types.size());
        NEXT_TYPE: for (String type : types) {
            Set<String> facets = model.getDocumentTypeFacets(type);
            for (String facet : info.mixinsExcluded) {
                if (facets.contains(facet)) {
                    continue NEXT_TYPE;
                }
            }
            for (String facet : info.mixinsAllRequired) {
                if (!facets.contains(facet)) {
                    continue NEXT_TYPE;
                }
            }
            if (!info.mixinsAnyRequired.isEmpty()) {
                Set<String> intersection = new HashSet<String>(info.mixinsAnyRequired);
                intersection.retainAll(facets);
                if (intersection.isEmpty()) {
                    continue NEXT_TYPE;
                }
            }
            // this type is good
            typeStrings.add("?");
            whereParams.add(type);
        }
        if (typeStrings.isEmpty()) {
            return null; // mixins excluded all types, no match possible
        }
        whereClauses.add(String.format("%s IN (%s)",
                dataHierTable.getColumn(model.MAIN_PRIMARY_TYPE_KEY).getFullQuotedName(),
                StringUtils.join(typeStrings, ", ")));

        /*
         * Add clause for immutable match.
         */

        if (docKind == DocKind.DIRECT && info.immutableClause != null) {
            String where = String.format("%s IS %s",
                    database.getTable(model.VERSION_TABLE_NAME).getColumn(model.MAIN_KEY).getFullQuotedName(),
                    info.immutableClause.booleanValue() ? "NOT NULL" : "NULL");
            whereClauses.add(where);
        }

        /*
         * Parse the WHERE clause from the original query, and deduce from
         * it actual WHERE clauses and potential JOINs.
         */

        WhereBuilder whereBuilder;
        try {
            whereBuilder = new WhereBuilder(database, session, hierTable, hierId, dataHierTable, dataHierId,
                    docKind == DocKind.PROXY, aliasColumns);
        } catch (QueryMakerException e) {
            throw new StorageException(e.getMessage(), e);
        }
        if (info.wherePredicate != null) {
            info.wherePredicate.accept(whereBuilder);
            // JOINs added by fulltext queries
            leftJoins.addAll(whereBuilder.leftJoins);
            leftJoinsParams.addAll(whereBuilder.leftJoinsParams);
            implicitJoins.addAll(whereBuilder.implicitJoins);
            implicitJoinsParams.addAll(whereBuilder.implicitJoinsParams);
            // WHERE clause
            String where = whereBuilder.buf.toString();
            if (where.length() != 0) {
                whereClauses.add(where);
                whereParams.addAll(whereBuilder.whereParams);
            }
        }

        /*
         * Security check.
         */

        if (queryFilter.getPrincipals() != null) {
            Serializable principals = queryFilter.getPrincipals();
            Serializable permissions = queryFilter.getPermissions();
            if (!dialect.supportsArrays()) {
                principals = StringUtils.join((String[]) principals, '|');
                permissions = StringUtils.join((String[]) permissions, '|');
            }
            if (dialect.supportsReadAcl()) {
                /* optimized read acl */
                whereClauses.add(dialect.getReadAclsCheckSql("r.acl_id"));
                whereParams.add(principals);
                joins.add(String.format("%s AS r ON %s = r.id", model.HIER_READ_ACL_TABLE_NAME, hierId));
            } else {
                whereClauses.add(dialect.getSecurityCheckSql(hierId));
                whereParams.add(principals);
                whereParams.add(permissions);
            }
        }

        /*
         * Columns on which to do ordering.
         */

        String selectWhat = hierId;
        // always add the name, it will be used for intalio crm
        selectWhat += ", " + hierName;

        if (aliasColumns) {
            // UNION, so we need all orderable columns, aliased
            int n = 0;
            for (String key : info.orderKeys) {
                Column column = whereBuilder.findColumn(key, false, true);
                String qname = column.getFullQuotedName();
                selectWhat += ", " + qname + " AS " + dialect.openQuote() + COL_ORDER_ALIAS_PREFIX + ++n
                        + dialect.closeQuote();
            }
        }

        /*
         * Order by. Compute it just once. May use just aliases.
         */

        if (orderBy == null && sqlQuery.orderBy != null) {
            whereBuilder.buf.setLength(0);
            sqlQuery.orderBy.accept(whereBuilder);
            orderBy = whereBuilder.buf.toString();
        }

        /*
         * Resulting select.
         */

        select = new Select(null);
        select.setWhat(selectWhat);
        leftJoins.addFirst(StringUtils.join(joins, " JOIN "));
        String from = StringUtils.join(leftJoins, " LEFT JOIN ");
        if (!implicitJoins.isEmpty()) {
            implicitJoins.addFirst(from);
            from = StringUtils.join(implicitJoins, ", ");
        }
        select.setFrom(from);
        select.setWhere(StringUtils.join(whereClauses, " AND "));
        selectParams.addAll(leftJoinsParams);
        selectParams.addAll(implicitJoinsParams);
        selectParams.addAll(whereParams);

        statements.add(select.getStatement());
    }

    /*
     * Create the whole select.
     */

    if (statements.size() > 1) {
        select = new Select(null);
        String selectWhat = hier.getColumn(model.MAIN_KEY).getQuotedName();
        selectWhat = selectWhat + ", " + hier.getColumn(model.HIER_CHILD_NAME_KEY).getQuotedName();
        select.setWhat(selectWhat);

        // note that Derby has bizarre restrictions on parentheses placement
        // around UNION, see http://issues.apache.org/jira/browse/DERBY-2374
        String from = '(' + StringUtils.join(statements, " UNION ALL ") + ')';
        if (dialect.needsAliasForDerivedTable()) {
            from += " AS " + dialect.openQuote() + UNION_ALIAS + dialect.closeQuote();
        }
        select.setFrom(from);
    }
    select.setOrderBy(orderBy);

    List<Column> whatColumns = Collections.singletonList(hier.getColumn(model.MAIN_KEY));
    Query q = new Query();
    q.selectInfo = new SQLInfoSelect(select.getStatement(), whatColumns, null, null);
    q.selectParams = selectParams;
    return q;
}

From source file:com.funambol.foundation.items.dao.PIMCalendarDAO.java

/**
 * Retrieves the UID list of the calendars considered to be "twins" of a
 * given calendar./* ww  w. ja  v a  2  s. c  o m*/
 *
 * @param c the Calendar object representing the calendar whose twins
 *          need be found. In the present implementation, only the following
 *          data matter: 
 *          <BR>for events <UL><LI>date start<LI>date end<LI>subject</UL>
 *          for tasks <UL><LI>date end<LI>subject</UL>
 * @throws DAOException
 * @return a List of UIDs (as String objects) that may be empty but not null
 */
public List getTwinItems(Calendar c) throws DAOException {

    if (log.isTraceEnabled()) {
        log.trace("PIMCalendarDAO getTwinItems begin");
    }

    LinkedList<String> twins = new LinkedList<String>();
    Connection con = null;
    PreparedStatement ps = null;
    ResultSet rs = null;

    if (!isTwinSearchAppliableOn(c)) {
        if (log.isTraceEnabled()) {
            log.trace("Item with no dtStart, dtEnd, summary: twin search skipped.");
        }
        return twins;
    }

    try {

        // Looks up the data source when the first connection is created
        con = getUserDataSource().getRoutedConnection(userId);
        con.setReadOnly(true);

        Date dtStart;
        Date dtEnd;
        Date dueTomorrowNoon = null;
        Date dueYesterdayNoon = null;

        dtStart = getDateFromString(c.getCalendarContent().isAllDay(),
                Property.stringFrom(c.getCalendarContent().getDtStart()), "000000");
        dtEnd = getDateFromString(c.getCalendarContent().isAllDay(),
                Property.stringFrom(c.getCalendarContent().getDtEnd()), "235900");

        if ((dtEnd != null) && (c.getCalendarContent() instanceof Task)) {
            java.util.Calendar noon = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
            noon.setTime(dtEnd);
            noon.set(java.util.Calendar.HOUR_OF_DAY, 12);
            noon.set(java.util.Calendar.MINUTE, 0);
            noon.set(java.util.Calendar.MILLISECOND, 0);
            noon.add(java.util.Calendar.DATE, +1);
            dueTomorrowNoon = noon.getTime();
            noon.add(java.util.Calendar.DATE, -2); // go back and another -1
            dueYesterdayNoon = noon.getTime();
        }

        StringBuffer sqlGetCalendarTwinList = new StringBuffer(SQL_GET_FNBL_PIM_CALENDAR_ID_LIST_BY_USER);

        String subject = Property.stringFrom(c.getCalendarContent().getSummary(), true); // Empty implies null;

        if ("null".equals(subject)) {
            subject = null;
        }
        if (subject == null) {
            sqlGetCalendarTwinList.append(SQL_AND_NO_SUBJECT_IS_SET);
        } else {
            sqlGetCalendarTwinList.append(SQL_AND_SUBJECT_EQUALS_QUESTIONMARK);
        }
        if (c.getCalendarContent() instanceof Event) {
            if (dtStart == null) {
                sqlGetCalendarTwinList.append(SQL_AND_NO_DSTART_IS_SET);
            } else {
                sqlGetCalendarTwinList.append(SQL_AND_DSTART_EQUALS_QUESTIONMARK);
            }
        }
        if (dtEnd == null) {
            // In method updateItems() while storing the Event in the db, if
            // the End Date is empty it is filled with the Start Date.
            // Filling the empty EndDate with the StartDate is done only for
            // Events and not for Tasks.
            // See "Fix for Siemens S56 end date issue" in method 
            // updateItems().
            // So in order to find the twins, if the incoming Event has an 
            // empty EndDate we seek into the db for Events with EndDate 
            // equal to the StartDate value.
            if (c.getCalendarContent() instanceof Task) {
                sqlGetCalendarTwinList.append(SQL_AND_NO_DEND_IS_SET);
            } else {
                sqlGetCalendarTwinList.append(SQL_AND_DEND_EQUALS_QUESTIONMARK);
            }
        } else {
            if (c.getCalendarContent() instanceof Task) {
                sqlGetCalendarTwinList.append(SQL_AND_DEND_IN_INTERVAL);
            } else {
                sqlGetCalendarTwinList.append(SQL_AND_DEND_EQUALS_QUESTIONMARK);
            }
        }

        if (c.getCalendarContent() instanceof Event) {
            sqlGetCalendarTwinList.append(SQL_FILTER_BY_TYPE[CALENDAR_EVENT_TYPE]);
        } else {
            sqlGetCalendarTwinList.append(SQL_FILTER_BY_TYPE[CALENDAR_TASK_TYPE]);
        }

        //
        // If funambol is not in the debug mode it is not possible to print 
        // the calendar info because it contains sensitive data.
        //
        if (Configuration.getConfiguration().isDebugMode()) {

            if (log.isTraceEnabled()) {

                StringBuilder sb = new StringBuilder(100);
                sb.append("Looking for items having: ");

                if (subject == null || subject.length() == 0) {
                    sb.append("\n> subject: <N/A>");
                } else {
                    sb.append("\n> subject: '").append(subject).append('\'');
                }
                if (c.getCalendarContent() instanceof Event) {
                    if (dtStart == null) {
                        sb.append("\n> start date: <N/A>");
                    } else {
                        sb.append("\n> start date: ").append(dtStart);
                    }
                    if (dtEnd == null) {
                        sb.append("\n> end date: <N/A>");
                    } else {
                        sb.append("\n> end date: ").append(dtEnd);
                    }
                } else { // It's a task
                    if (dtEnd == null) {
                        sb.append("\n> due date: <N/A>");
                    } else {
                        sb.append("\n> due date: between ").append(dueYesterdayNoon)
                                .append("\n>           and ").append(dueTomorrowNoon)
                                .append(",\n>           possibly ").append(dtEnd);
                    }
                }

                log.trace(sb.toString());
            }
        }

        sqlGetCalendarTwinList.append(SQL_ORDER_BY_ID);

        ps = con.prepareStatement(sqlGetCalendarTwinList.toString());

        int k = 1;
        ps.setString(k++, userId);
        if (subject != null) {
            ps.setString(k++, subject.toLowerCase(Locale.ENGLISH));
        }
        if (dtStart != null) {
            if (c.getCalendarContent() instanceof Event) {
                ps.setTimestamp(k++, new Timestamp(dtStart.getTime()));
            }
        }
        if (dtEnd != null) {
            if (c.getCalendarContent() instanceof Task) {
                ps.setTimestamp(k++, new Timestamp(dueYesterdayNoon.getTime()));
                ps.setTimestamp(k++, new Timestamp(dueTomorrowNoon.getTime()));
            } else {
                ps.setTimestamp(k++, new Timestamp(dtEnd.getTime()));
            }
        } else {
            // In method updateItems() while storing the Event in the db, if
            // the End Date is empty it is filled with the Start Date.
            // Filling the empty EndDate with the StartDate is done only for
            // Events and not for Tasks.
            // See "Fix for Siemens S56 end date issue" in method 
            // updateItems().
            // So in order to find the twins, if the incoming Event has an 
            // empty EndDate we seek into the db for Events with EndDate 
            // equal to the StartDate value.
            if (c.getCalendarContent() instanceof Event) {
                ps.setTimestamp(k++, new Timestamp(dtStart.getTime()));
            }
        }

        rs = ps.executeQuery();
        long twinId;
        Timestamp twinDueDate;
        while (rs.next()) {
            if (c.getCalendarContent() instanceof Event) {
                twinId = rs.getLong(1);
                // dend is not relevant in this case
                if (log.isTraceEnabled()) {
                    log.trace("Twin event found: " + twinId);
                }

                twins.add(Long.toString(twinId));

            } else { // it's a Task
                twinId = rs.getLong(1);
                twinDueDate = rs.getTimestamp(2);
                if (log.isTraceEnabled()) {
                    log.trace("Twin task found: " + twinId);
                }

                if ((dtEnd != null) && (twinDueDate != null) && twinDueDate.getTime() == dtEnd.getTime()) {
                    twins.addFirst(Long.toString(twinId));
                    if (log.isTraceEnabled()) {
                        log.trace("Item " + twinId + " is an exact due-date match.");
                    }
                } else {
                    twins.addLast(Long.toString(twinId));
                }
            }
        }

    } catch (Exception e) {
        throw new DAOException("Error retrieving twin. ", e);
    } finally {
        DBTools.close(con, ps, rs);
    }

    if (log.isTraceEnabled()) {
        log.trace("PIMCalendarDAO getTwinItems end");
    }

    return twins;
}