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 org.openconcerto.utils.CollectionUtils;
import org.openconcerto.utils.convertor.NumberConvertor;

import java.util.Collections;
import java.util.List;
import java.util.Objects;

import net.jcip.annotations.Immutable;

/**
 * Allow to store a reference to a row with less memory than {@link SQLRow}.
 * 
 * @author sylvain
 * @see SQLTable#createRowRef(Number)
 * @see SQLRowAccessor#getRowRef()
 */
@Immutable
public final class RowRef {

    // need to convert so that equals() work (because Number.equals() doesn't exist)
    static private Number convert(final SQLTable table, final Number n) {
        // avoid method calls if null
        return n == null ? null : NumberConvertor.convertExact(n, table.getKey().getType().getJavaType().asSubclass(Number.class));
    }

    private final SQLTable table;
    private final List<?> pk;
    private final Number id;

    RowRef(final SQLTable table, final List<?> pk) {
        this(table, pk, false);
    }

    RowRef(final SQLTable table, final List<?> pk, final boolean safe) {
        this(table, Objects.requireNonNull(pk), null, safe);
    }

    RowRef(final SQLTable table, final Number id) {
        this(table, null, Objects.requireNonNull(id), false);
    }

    private RowRef(final SQLTable table, final List<?> pk, final Number id, final boolean safe) {
        assert (pk == null) != (id == null);
        if (id != null && !table.isRowable())
            throw new IllegalStateException("Not rowable : " + table.getSQLName());
        else if (!safe && pk != null && pk.size() != table.getPrimaryKeyFields().size())
            throw new IllegalArgumentException("Wrong number of items");
        this.table = Objects.requireNonNull(table);
        if (id != null || table.isRowable()) {
            this.id = convert(table, id != null ? id : (Number) pk.get(0));
            this.pk = Collections.singletonList(this.id);
        } else {
            this.id = null;
            this.pk = safe ? pk : CollectionUtils.toImmutableList(pk);
        }
    }

    public final SQLTable getTable() {
        return this.table;
    }

    public final List<?> getPK() {
        return this.pk;
    }

    public final Number getID() {
        return this.id;
    }

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

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

    @Override
    public String toString() {
        return this.getClass().getSimpleName() + " " + this.getTable() + " " + this.getPK();
    }
}