OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Blame | Last modification | View Log | RSS feed

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
 * 
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each file.
 */
 
 package org.openconcerto.sql.model;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;

import org.apache.commons.dbutils.RowProcessor;

import net.jcip.annotations.Immutable;

@Immutable
public final class SQLFieldRowProcessor implements RowProcessor {

    private final List<String> names;
    private final int rsOffset;
    private Boolean uniqueNames;

    public SQLFieldRowProcessor(final SQLTable table, final List<String> fields) {
        this(0, fields, table::getField);
    }

    public SQLFieldRowProcessor(final List<? extends FieldRef> fields) {
        this(0, fields);
    }

    public SQLFieldRowProcessor(final int rsOffset, final List<? extends FieldRef> fields) {
        this(rsOffset, fields, FieldRef::getField);
    }

    private <F> SQLFieldRowProcessor(final int rsOffset, final List<? extends F> fields, final Function<? super F, SQLField> func) {
        final List<String> names = new ArrayList<>(fields.size());
        for (final F ref : fields) {
            if (ref == null) {
                names.add(null);
            } else {
                final SQLField f = func.apply(ref);
                names.add(f.getName());
            }
        }
        this.names = Collections.unmodifiableList(names);
        this.rsOffset = rsOffset;
        this.uniqueNames = null;
    }

    public final List<String> getFieldNames() {
        return this.names;
    }

    public final boolean areNamesUnique() {
        if (this.uniqueNames == null) {
            this.uniqueNames = new HashSet<>(this.names).size() == this.names.size();
        }
        return this.uniqueNames.booleanValue();
    }

    public final Object getObject(final ResultSet rs, final int rsIndex) throws SQLException {
        return rs.getObject(rsIndex + this.rsOffset);
    }

    @Override
    public Object[] toArray(ResultSet rs) throws SQLException {
        final int count = this.names.size();
        final Object[] result = new Object[count];
        for (int i = 0; i < count; i++) {
            result[i] = getObject(rs, i + 1);
        }
        return result;
    }

    @SuppressWarnings("rawtypes")
    @Override
    public Object toBean(ResultSet rs, Class type) throws SQLException {
        throw new UnsupportedOperationException();
    }

    @SuppressWarnings("rawtypes")
    @Override
    public List toBeanList(ResultSet rs, Class type) throws SQLException {
        throw new UnsupportedOperationException();
    }

    @Override
    public Map<String, Object> toMap(ResultSet rs) throws SQLException {
        final int count = this.names.size();
        final Map<String, Object> result = new HashMap<>();
        for (int i = 0; i < count; i++) {
            final String name = this.names.get(i);
            if (name != null) {
                result.put(name, getObject(rs, i + 1));
            }
        }
        return result;
    }

    @Override
    public int hashCode() {
        return Objects.hash(this.names, this.rsOffset);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        final SQLFieldRowProcessor other = (SQLFieldRowProcessor) obj;
        return this.rsOffset == other.rsOffset && this.names.equals(other.names);
    }
}