Example usage for java.sql ResultSet getBoolean

List of usage examples for java.sql ResultSet getBoolean

Introduction

In this page you can find the example usage for java.sql ResultSet getBoolean.

Prototype

boolean getBoolean(String columnLabel) throws SQLException;

Source Link

Document

Retrieves the value of the designated column in the current row of this ResultSet object as a boolean in the Java programming language.

Usage

From source file:com.flexive.ejb.beans.workflow.StepEngineBean.java

/**
 * {@inheritDoc}/*from  w  w w.  j a v  a2s  . c o  m*/
 */
@Override
public List<StepPermission> loadAllStepsForUser(long userId) throws FxApplicationException {
    UserTicket ticket = FxContext.getUserTicket();
    // Select all step ids
    final String sql =
            //                 1    ,   2         ,      3
            "SELECT DISTINCT step.ID,aclug.ACL,step.WORKFLOW,"
                    // 4        ,  5       ,   6     ,  7         ,   8      ,      9        , 10
                    + " aclug.PEDIT,aclug.PREAD,aclug.PREMOVE,aclug.PEXPORT,aclug.PREL,aclug.PCREATE,step.STEPDEF"
                    + " FROM " + TBL_ACLS + " acl," + TBL_ACLS_ASSIGNMENT + " aclug," + TBL_WORKFLOW_STEP
                    + " step" + " WHERE" + " aclug.ACL=acl.ID" + " AND acl.CAT_TYPE="
                    + ACLCategory.WORKFLOW.getId() + " AND aclug.USERGROUP IN (SELECT DISTINCT USERGROUP FROM "
                    + TBL_ASSIGN_GROUPS + " WHERE ACCOUNT=" + userId + " AND USERGROUP<>"
                    + UserGroup.GROUP_OWNER + ")" + " AND step.ACL=acl.ID";

    // Security
    if (!ticket.isGlobalSupervisor()) {
        if (ticket.getUserId() != userId) {
            FxNoAccessException na = new FxNoAccessException("You may not load the Steps for a other user");
            if (LOG.isInfoEnabled())
                LOG.info(na);
            throw na;
        }
    }

    // Obtain a database connection
    Connection con = null;
    Statement stmt = null;
    try {
        con = Database.getDbConnection();

        // Load all steps in the database
        stmt = con.createStatement();
        ResultSet rs = stmt.executeQuery(sql);
        //ArrayList result = new ArrayList(50);
        Hashtable<Integer, StepPermission> result = new Hashtable<Integer, StepPermission>(50);

        while (rs != null && rs.next()) {
            // Fill in a step object
            Integer stepId = rs.getInt(1);
            int workflowId = rs.getInt(3);
            boolean mayEdit = rs.getBoolean(4);
            boolean mayRead = rs.getBoolean(5);
            boolean mayDelete = rs.getBoolean(6);
            boolean mayExport = rs.getBoolean(7);
            boolean mayRelate = rs.getBoolean(8);
            boolean mayCreate = rs.getBoolean(9);
            int stepDefinitionId = rs.getInt(10);
            StepPermissionEdit data;
            StepPermission stepPerm = result.get(stepId);
            if (stepPerm == null) {
                data = new StepPermissionEdit(new StepPermission(stepId, stepDefinitionId, workflowId, mayRead,
                        mayEdit, mayRelate, mayDelete, mayExport, mayCreate));
            } else {
                data = new StepPermissionEdit(stepPerm);
                if (mayDelete)
                    data.setMayDelete(true);
                if (mayEdit)
                    data.setMayEdit(true);
                if (mayExport)
                    data.setMayExport(true);
                if (mayRelate)
                    data.setMayRelate(true);
                if (mayRead)
                    data.setMayRead(true);
                if (mayCreate)
                    data.setMayCreate(true);
            }
            result.put(stepId, data);
        }

        return new ArrayList<StepPermission>(result.values());
    } catch (SQLException exc) {
        throw new FxLoadException(LOG, "ex.step.load.user", exc, userId, exc.getMessage());
    } finally {
        Database.closeObjects(StepEngineBean.class, con, stmt);
    }

}

From source file:com.p000ison.dev.simpleclans2.converter.Converter.java

public void convertKills() throws SQLException {
    ResultSet result = from.query("SELECT * FROM `sc_kills`;");

    while (result.next()) {
        Timestamp date;/*from  ww  w  .  ja  v a  2s. co  m*/
        try {
            date = result.getTimestamp("date");
        } catch (Exception e) {
            date = new Timestamp(System.currentTimeMillis());
        }
        insertKill(result.getString("attacker"), result.getString("attacker_tag"), result.getString("victim"),
                result.getString("victim_tag"), result.getString("kill_type"), result.getBoolean("war"), date);
    }
}

From source file:de.static_interface.reallifeplugin.module.contract.database.table.ContractUserOptionsTable.java

@Override
public ContractUserOptionsRow[] deserialize(ResultSet rs) throws SQLException {
    int rowcount = 0;
    if (rs.last()) {
        rowcount = rs.getRow();//from   w w  w.j a v  a  2 s .c  om
        rs.beforeFirst();
    }

    ContractUserOptionsRow[] rows = new ContractUserOptionsRow[rowcount];
    int i = 0;

    while (rs.next()) {
        ContractUserOptionsRow row = new ContractUserOptionsRow();
        if (hasColumn(rs, "id")) {
            row.id = rs.getInt("id");
        }
        if (hasColumn(rs, "user_id")) {
            row.userId = rs.getInt("userId");
        }
        if (hasColumn(rs, "contract_id")) {
            row.contractId = rs.getInt("contract_id");
        }
        if (hasColumn(rs, "isCreator")) {
            row.isCreator = rs.getBoolean("isCreator");
        }
        if (hasColumn(rs, "money")) {
            row.money = rs.getDouble("money");
            if (rs.wasNull()) {
                row.money = null;
            }
        }
        rows[i] = row;
        i++;
    }
    return rows;
}

From source file:com.adito.tunnels.JDBCTunnelDatabase.java

Tunnel buildTunnel(ResultSet rs) throws Exception {
    Timestamp cd = rs.getTimestamp("date_created");
    Calendar c = Calendar.getInstance();
    c.setTimeInMillis(cd == null ? System.currentTimeMillis() : cd.getTime());
    Timestamp ad = rs.getTimestamp("date_amended");
    Calendar a = Calendar.getInstance();
    a.setTimeInMillis(ad == null ? System.currentTimeMillis() : ad.getTime());
    return new DefaultTunnel(rs.getInt("realm_id"), rs.getString("name"), rs.getString("description"),
            rs.getInt("tunnel_id"), rs.getInt("type"), rs.getBoolean("auto_start"), rs.getString("transport"),
            rs.getString("username"), rs.getInt("source_port"),
            new HostService(rs.getString("destination_host"), rs.getInt("destination_port")),
            rs.getString("source_interface"), c, a);
}

From source file:com.nextep.designer.sqlgen.db2.impl.DB2Capturer.java

/**
 * Returns a <code>Collection</code> of <code>ISynonym</code> objects representing the synonyms
 * described by each row of the specified <code>ResultSet</code>.
 * /*from   w  w w .j  a v  a  2 s  . com*/
 * @param rset a {@link ResultSet} where each line is a description of a synonym; must not be
 *        <code>null</code>
 * @param monitor the {@link IProgressMonitor} to notify while capturing objects
 * @return a {@link Collection} of {@link ISynonym} objects if specified <code>ResultSet</code>
 *         is not empty, an empty <code>Collection</code> otherwise
 * @throws SQLException if a database access error occurs
 */
private Collection<ISynonym> getSynonymsFromResultSet(ICaptureContext context, ResultSet rset,
        IProgressMonitor monitor) throws SQLException {
    Collection<ISynonym> synonyms = new ArrayList<ISynonym>();
    final String schema = context.getSchema();
    while (rset.next()) {
        final boolean isPublic = rset.getBoolean("is_public"); //$NON-NLS-1$
        final String synName = rset.getString("synname"); //$NON-NLS-1$
        final String synDesc = rset.getString("remarks"); //$NON-NLS-1$
        final String synType = rset.getString("syntype"); //$NON-NLS-1$
        final String refDbObjName = rset.getString("refname"); //$NON-NLS-1$
        final String refDbObjSchemaName = rset.getString("refschema"); //$NON-NLS-1$

        if (synName != null && !"".equals(synName.trim())) { //$NON-NLS-1$
            if (LOGGER.isDebugEnabled()) {
                String syscatTableName = null;
                String fieldPrefix = null;
                if (synType.equals(IBasicTable.TYPE_ID)) {
                    syscatTableName = "TABLES"; //$NON-NLS-1$
                    fieldPrefix = "TAB"; //$NON-NLS-1$
                } else if (synType.equals(ISequence.TYPE_ID)) {
                    syscatTableName = "SEQUENCES"; //$NON-NLS-1$
                    fieldPrefix = "SEQ"; //$NON-NLS-1$
                }
                String logPrefix = "[" + synName + "]"; //$NON-NLS-1$ //$NON-NLS-2$
                String tabPrefix = "SYSCAT." + syscatTableName; //$NON-NLS-1$
                LOGGER.debug("= " + logPrefix + " Synonym Metadata ="); //$NON-NLS-1$ //$NON-NLS-2$
                LOGGER.debug(logPrefix + "[" + tabPrefix + ".TYPE] A"); //$NON-NLS-1$ //$NON-NLS-2$
                LOGGER.debug(logPrefix + "[" + tabPrefix + "." + fieldPrefix + "SCHEMA] " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                        + (isPublic ? "SYSPUBLIC" : schema)); //$NON-NLS-1$
                LOGGER.debug(logPrefix + "[" + tabPrefix + ".BASE_" + fieldPrefix + "NAME] " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                        + refDbObjName);
                LOGGER.debug(logPrefix + "[" + tabPrefix + ".BASE_" + fieldPrefix + "SCHEMA] " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                        + (null == refDbObjSchemaName ? schema : refDbObjSchemaName));
                LOGGER.debug(logPrefix + "[" + tabPrefix + ".REMARKS] " + synDesc); //$NON-NLS-1$ //$NON-NLS-2$
            }

            // FIXME [BGA]: Remove this test when the public and referred object type
            // attributes are supported, either by the generic model or the DB2 specific
            // model.
            if (!isPublic && synType.equals(IBasicTable.TYPE_ID)) {
                IVersionable<ISynonym> vSynonym = VersionableFactory.createVersionable(ISynonym.class);

                Synonym synonym = (Synonym) vSynonym.getVersionnedObject().getModel();
                synonym.setName(synName);
                synonym.setDescription(synDesc);
                synonym.setRefDbObjSchemaName(refDbObjSchemaName);
                synonym.setRefDbObjName(refDbObjName);

                synonyms.add(synonym);
                CaptureHelper.updateMonitor(monitor, getCounter(), 5, 1);
            }
        }
    }

    return synonyms;
}

From source file:com.flexive.core.security.FxDBAuthentication.java

/**
 * Login a user using flexive's database
 *
 * @param loginname name of the user/*from   w ww  .  j  a  va2s.c o  m*/
 * @param password plaintext password
 * @param callback callback providing datasource, ejb context and "take over"
 * @return Authenticated UserTicket
 * @throws FxAccountInUseException   on errors
 * @throws FxLoginFailedException    on errors
 * @throws FxAccountExpiredException on errors
 */
public static UserTicket login(String loginname, String password, FxCallback callback)
        throws FxAccountInUseException, FxLoginFailedException, FxAccountExpiredException {
    final long SYS_UP = CacheAdmin.getInstance().getSystemStartTime();
    FxContext inf = FxContext.get();

    // Avoid null pointer exceptions
    if (password == null)
        password = "";
    if (loginname == null)
        loginname = "";

    final String applicationId = StringUtils.defaultString(inf.getApplicationId());
    if (StringUtils.isBlank(applicationId)) {
        LOG.warn("Login: application ID is not set");
    }

    String curSql;
    PreparedStatement ps = null;
    Connection con = null;
    try {
        // Obtain a database connection
        con = callback.getDataSource().getConnection();
        //               1-6 7      8           9              10                 11           12       13      14         15       16
        curSql = "SELECT d.*,a.ID,a.IS_ACTIVE,a.IS_VALIDATED,a.ALLOW_MULTILOGIN,a.VALID_FROM,a.VALID_TO,NOW(),a.PASSWORD,a.MANDATOR,a.LOGIN_NAME "
                + "FROM " + TBL_ACCOUNTS + " a " + "LEFT JOIN "
                + " (SELECT ID,ISLOGGEDIN,LAST_LOGIN,LAST_LOGIN_FROM,FAILED_ATTEMPTS,AUTHSRC FROM "
                + TBL_ACCOUNT_DETAILS
                + " WHERE APPLICATION=? ORDER BY LAST_LOGIN DESC) d ON a.ID=d.ID WHERE UPPER(a.LOGIN_NAME)=UPPER(?)";
        ps = con.prepareStatement(curSql);
        ps.setString(1, applicationId);
        ps.setString(2, loginname);
        final ResultSet rs = ps.executeQuery();

        // Anything found?
        if (rs == null || !rs.next())
            throw new FxLoginFailedException("Login failed (invalid user or password)",
                    FxLoginFailedException.TYPE_USER_OR_PASSWORD_NOT_DEFINED);

        // check if the hashed password matches the hash stored in the database
        final long id = rs.getLong(7);
        final String dbLoginName = rs.getString(16); // use DB login name for non-lowercase login names
        final String dbPassword = rs.getString(14);
        boolean passwordMatches = FxSharedUtils.hashPassword(id, dbLoginName, password).equals(dbPassword);
        if (!passwordMatches && "supervisor".equalsIgnoreCase(loginname)) {
            // before 3.2.0 the default supervisor password was incorrectly hashed against the lower-cased login name
            passwordMatches = FxSharedUtils.hashPassword(id, "supervisor", password).equals(dbPassword);
        }
        if (!passwordMatches && !callback.isCalledAsGlobalSupervisor()) {
            increaseFailedLoginAttempts(con, id);
            throw new FxLoginFailedException("Login failed (invalid user or password)",
                    FxLoginFailedException.TYPE_USER_OR_PASSWORD_NOT_DEFINED);
        }

        // Read data
        final boolean loggedIn = rs.getBoolean(2);
        final Date lastLogin = new Date(rs.getLong(3));
        final String lastLoginFrom = rs.getString(4);
        final long failedAttempts = rs.getLong(5);
        final boolean active = rs.getBoolean(8);
        final boolean validated = rs.getBoolean(9);
        final boolean allowMultiLogin = rs.getBoolean(10);
        final Date validFrom = new Date(rs.getLong(11));
        final Date validTo = new Date(rs.getLong(12));
        final Date dbNow = rs.getTimestamp(13);
        final long mandator = rs.getLong(15);

        // Account active?
        if (!active || !validated || (CacheAdmin.isEnvironmentLoaded()
                && !CacheAdmin.getEnvironment().getMandator(mandator).isActive())) {
            if (LOG.isDebugEnabled())
                LOG.debug("Login for user [" + loginname + "] failed, account is inactive. Active=" + active
                        + ", Validated=" + validated + ", Mandator active: "
                        + CacheAdmin.getEnvironment().getMandator(mandator).isActive());
            increaseFailedLoginAttempts(con, id);
            throw new FxLoginFailedException("Login failed, account is inactive.",
                    FxLoginFailedException.TYPE_INACTIVE_ACCOUNT);
        }

        // Account date from-to valid?
        //Compute the day AFTER the dValidTo
        Calendar endDate = Calendar.getInstance();
        endDate.setTime(validTo);
        endDate.add(Calendar.DAY_OF_MONTH, 1);
        if (validFrom.getTime() > dbNow.getTime() || endDate.getTimeInMillis() < dbNow.getTime()) {
            SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
            if (LOG.isDebugEnabled())
                LOG.debug("Login for user [" + loginname + "] failed, from/to date not valid. from='"
                        + sdf.format(validFrom) + "' to='" + validTo + "'");
            increaseFailedLoginAttempts(con, id);
            throw new FxAccountExpiredException(loginname, dbNow);
        }

        // Check 'Account in use and takeOver false'
        if (!allowMultiLogin && !callback.getTakeOverSession() && loggedIn && lastLogin != null) {
            // Only if the last login time was AFTER the system started
            if (lastLogin.getTime() >= SYS_UP) {
                FxAccountInUseException aiu = new FxAccountInUseException(loginname, lastLoginFrom, lastLogin);
                if (LOG.isInfoEnabled())
                    LOG.info(aiu);
                // don't log this as an invalid login attempt - this happens routinely when a session times
                // out and the cached session data has not been evicted by the maintenance task yet

                //increaseFailedLoginAttempts(con, id);
                throw aiu;
            }
        }

        // Clear any old data
        curSql = "DELETE FROM " + TBL_ACCOUNT_DETAILS + " WHERE ID=? AND APPLICATION=?";
        ps.close();
        ps = con.prepareStatement(curSql);
        ps.setLong(1, id);
        ps.setString(2, applicationId);
        ps.executeUpdate();

        // Mark user as active in the database
        // This can lead to duplicate rows for a user/application for concurrent logins (e.g. WebDAV clients),
        // but we prefer this to actually locking the complete table before updates. (FX-868)
        curSql = "INSERT INTO " + TBL_ACCOUNT_DETAILS
                + " (ID,APPLICATION,ISLOGGEDIN,LAST_LOGIN,LAST_LOGIN_FROM,FAILED_ATTEMPTS,AUTHSRC) "
                + "VALUES (?,?,?,?,?,?,?)";
        ps.close();
        ps = con.prepareStatement(curSql);
        ps.setLong(1, id);
        ps.setString(2, applicationId);
        ps.setBoolean(3, true);
        ps.setLong(4, System.currentTimeMillis());
        ps.setString(5, inf.getRemoteHost());
        ps.setLong(6, 0); //reset failed attempts
        ps.setString(7, AuthenticationSource.Database.name());
        ps.executeUpdate();

        // Load the user and construct a user ticket
        try {
            final UserTicketImpl ticket = (UserTicketImpl) UserTicketStore.getUserTicket(loginname);
            ticket.setFailedLoginAttempts(failedAttempts);
            ticket.setAuthenticationSource(AuthenticationSource.Database);
            return ticket;
        } catch (FxApplicationException e) {
            if (callback.getSessionContext() != null)
                callback.getSessionContext().setRollbackOnly();
            throw new FxLoginFailedException(
                    e.getExceptionMessage().getLocalizedMessage(
                            CacheAdmin.getEnvironment().getLanguage(FxLanguage.DEFAULT_ID)),
                    FxLoginFailedException.TYPE_UNKNOWN_ERROR);
        }
    } catch (SQLException exc) {
        if (callback.getSessionContext() != null)
            callback.getSessionContext().setRollbackOnly();
        throw new FxLoginFailedException("Database error: " + exc.getMessage(),
                FxLoginFailedException.TYPE_SQL_ERROR);
    } finally {
        Database.closeObjects(FxDBAuthentication.class, con, ps);
    }
}

From source file:org.mayocat.shop.catalog.store.jdbi.mapper.ProductMapper.java

@Override
public Product map(int index, ResultSet resultSet, StatementContext statementContext) throws SQLException {
    try {//  ww  w  .  java 2 s .  co m
        Product product = new Product((UUID) resultSet.getObject("id"));
        product.setTenantId((UUID) resultSet.getObject("tenant_id"));
        if (resultSet.getObject("parent_id") != null) {
            product.setParentId((UUID) resultSet.getObject("parent_id"));
        }
        product.setSlug(resultSet.getString("slug"));
        product.setTitle(resultSet.getString("title"));
        product.setDescription(resultSet.getString("description"));
        product.setCreationDate(resultSet.getTimestamp("creation_date"));
        if (resultSet.getObject("on_shelf") != null) {
            product.setOnShelf(resultSet.getBoolean("on_shelf"));
        }
        product.setPrice(resultSet.getBigDecimal("price"));

        if (!Strings.isNullOrEmpty(resultSet.getString("taxes"))) {
            ObjectMapper mapper = new ObjectMapper();
            Map<String, String> taxes = mapper.readValue(resultSet.getString("taxes"),
                    new TypeReference<Map<String, String>>() {
                    });
            if (taxes.containsKey("vat")) {
                product.setVatRateId(taxes.get("vat"));
            }
        }

        product.setWeight(resultSet.getBigDecimal("weight"));
        if (resultSet.getObject("stock") != null) {
            product.setStock(resultSet.getInt("stock"));
        }
        product.setVirtual(resultSet.getBoolean("virtual"));
        UUID featuredImageId = (UUID) resultSet.getObject("featured_image_id");
        if (featuredImageId != null) {
            product.setFeaturedImageId(featuredImageId);
        }

        if (MapperUtils.hasColumn("localization_data", resultSet)
                && !Strings.isNullOrEmpty(resultSet.getString("localization_data"))) {
            ObjectMapper mapper = new ObjectMapper();
            Map<Locale, Map<String, Object>> localizedVersions = Maps.newHashMap();
            Map[] data = mapper.readValue(resultSet.getString("localization_data"), Map[].class);
            for (Map map : data) {

                localizedVersions.put(Locale.forLanguageTag((String) map.get("locale")),
                        (Map) map.get("entity"));
            }
            product.setLocalizedVersions(localizedVersions);
        }

        String model = resultSet.getString("model");
        if (!Strings.isNullOrEmpty(model)) {
            product.setModel(model);
        }
        String type = resultSet.getString("product_type");
        if (!Strings.isNullOrEmpty(type)) {
            product.setType(type);
        }

        if (resultSet.getArray("features") != null) {
            // There's no support for getting the pg uuid array as a Java UUID array (or even String array) at the time
            // this is written, we have to iterate over the array own result set and construct the Java array ourselves
            List<UUID> ids = new ArrayList<>();
            Array array = resultSet.getArray("features");
            if (array != null) {
                ResultSet featuresResultSet = array.getResultSet();
                while (featuresResultSet.next()) {
                    ids.add((UUID) featuresResultSet.getObject("value"));
                }
                product.setFeatures(ids);
            }
        }

        return product;
    } catch (IOException e) {
        throw new SQLException("Failed to de-serialize JSON data", e);
    }
}

From source file:com.alfaariss.oa.engine.authorization.jdbc.JDBCProfile.java

/**
 * Creates a profile object.//from  w  w  w .j a va2 s .  c o  m
 * @param oDataSource the JDBC datasource
 * @param oResultSet A resultset containing a row with profile information
 * @param sMethodsTable methods table
 * @throws AuthorizationException if creation fails
 */
public JDBCProfile(DataSource oDataSource, ResultSet oResultSet, String sMethodsTable)
        throws AuthorizationException {
    super();
    try {
        _logger = LogFactory.getLog(JDBCProfile.class);

        _sID = oResultSet.getString(COLUMN_PROFILE_ID);
        _sFriendlyName = oResultSet.getString(COLUMN_PROFILE_FRIENDLYNAME);
        if (_sFriendlyName == null) {
            StringBuffer sbWarn = new StringBuffer("No '");
            sbWarn.append(COLUMN_PROFILE_FRIENDLYNAME);
            sbWarn.append("' available for profile with id: ");
            sbWarn.append(_sID);
            _logger.error(sbWarn.toString());
            throw new AuthorizationException(SystemErrors.ERROR_RESOURCE_RETRIEVE);
        }

        _bEnabled = oResultSet.getBoolean(COLUMN_PROFILE_ENABLED);

        _listAuthorizationMethod = readMethods(oDataSource, sMethodsTable);
    } catch (AuthorizationException e) {
        throw e;
    } catch (Exception e) {
        _logger.fatal("Internal error during initialization", e);
        throw new AuthorizationException(SystemErrors.ERROR_INTERNAL);
    }
}

From source file:biz.vnc.helpers.LeadHelper.java

@Override
public boolean checkWriteAccess(String leadId, String userId) {
    String query = "select writeAccess from tbl_crm_share where leadId = ? AND userId = ?; ";
    try {/* w  w w  . j  av a  2s. c o  m*/
        preparedStatement = DBUtility.connection.prepareStatement(query);
        preparedStatement.setString(1, leadId);
        preparedStatement.setString(2, userId);
    } catch (SQLException e) {
        ZLog.err("VNC CRM for Zimbra", "Error in deleteSharedItems in LeadHelper", e);
    }
    ResultSet rs = dbu.select(preparedStatement);
    try {
        while (rs.next()) {
            return rs.getBoolean("writeAccess");
        }
    } catch (SQLException e) {
        ZLog.err("VNC CRM for Zimbra", "Error listSharedItems result set in Lead Helper Class", e);
    }
    return true;
}