OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 80 | Rev 93 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
17 ilm 1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
7
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
8
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
9
 * language governing permissions and limitations under the License.
10
 *
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
13
 
14
 package org.openconcerto.sql.view.list;
15
 
16
import org.openconcerto.sql.Log;
17
import org.openconcerto.sql.model.SQLRow;
18
import org.openconcerto.sql.model.SQLRowValues;
73 ilm 19
import org.openconcerto.sql.model.SQLRowValues.CreateMode;
17 ilm 20
import org.openconcerto.sql.model.SQLRowValuesListFetcher;
21
import org.openconcerto.sql.model.SQLSelect;
22
import org.openconcerto.sql.model.Where;
23
import org.openconcerto.sql.model.graph.Path;
20 ilm 24
import org.openconcerto.sql.request.BaseFillSQLRequest;
17 ilm 25
import org.openconcerto.sql.request.ListSQLRequest;
73 ilm 26
import org.openconcerto.sql.view.list.search.SearchQueue;
27
import org.openconcerto.utils.CollectionUtils;
83 ilm 28
import org.openconcerto.utils.ListMap;
17 ilm 29
import org.openconcerto.utils.cc.ITransformer;
30
 
31
import java.util.Collection;
32
import java.util.List;
33
import java.util.Map.Entry;
34
 
35
abstract class AbstractUpdateOneRunnable extends UpdateRunnable {
36
 
73 ilm 37
    public AbstractUpdateOneRunnable(ITableModel model, final SQLRow r) {
38
        super(model, r);
17 ilm 39
        if (this.getID() < SQLRow.MIN_VALID_ID)
40
            throw new IllegalArgumentException("id is not valid : " + this.getID());
41
    }
42
 
83 ilm 43
    protected final ListMap<Path, ListSQLLine> getAffectedPaths() {
73 ilm 44
        return this.getSearchQ().getAffectedPaths(this.getRow());
17 ilm 45
    }
46
 
83 ilm 47
    protected final void updateLines(ListMap<Path, ListSQLLine> paths) {
48
        for (final Entry<Path, ? extends Collection<ListSQLLine>> e : paths.entrySet()) {
17 ilm 49
            // eg SITE.ID_CONTACT_CHEF
50
            final Path p = e.getKey();
51
            // eg [SQLRowValues(SITE), SQLRowValues(SITE)]
52
            final List<ListSQLLine> lines = (List<ListSQLLine>) e.getValue();
53
            if (!lines.isEmpty()) {
54
                // deepCopy() instead of new SQLRowValues() otherwise the used line's graph will be
55
                // modified (eg the new instance would be linked to it)
73 ilm 56
                final SQLRowValues proto = getModel().getLinesSource().getParent().getMaxGraph().followPathToOne(p, CreateMode.CREATE_NONE, false).deepCopy();
57
                final String lastReferentField = SearchQueue.getLastReferentField(p);
58
                // there's only one path from the graph start to proto, and we will graft the newly
59
                // fetched values at the end of p, so remove other values
60
                if (lastReferentField != null) {
61
                    proto.put(lastReferentField, null);
62
                } else {
63
                    proto.clearReferents();
64
                    // keep only what has changed, eg CONTACT.NOM
65
                    proto.retainAll(getModifedFields());
66
                }
80 ilm 67
                // the modified fields aren't used at the path (e.g. if we display a row and its
68
                // same-table origin, the event was added by UpdateQueue.rowModified() since the
69
                // the modified fields are displayed for the primary row, but might not for the
70
                // origin)
71
                if (!proto.getFields().isEmpty()) {
72
                    // fetch the changed rowValues
73
                    // ATTN this doesn't use the original fetcher that was used in the updateAll
74
                    // MAYBE add a slower but accurate mode using the updateAll fetcher (and thus
75
                    // reloading rows from the primary table and not just the changed rows)
76
                    final SQLRowValuesListFetcher fetcher = SQLRowValuesListFetcher.create(proto);
77
                    BaseFillSQLRequest.setupForeign(fetcher);
78
                    final ITransformer<SQLSelect, SQLSelect> transf = new ITransformer<SQLSelect, SQLSelect>() {
79
                        @Override
80
                        public SQLSelect transformChecked(SQLSelect input) {
81
                            if (ListSQLRequest.getDefaultLockSelect())
82
                                input.addWaitPreviousWriteTXTable(getTable().getName());
83
                            return input.setWhere(new Where(getTable().getKey(), "=", getID()));
84
                        }
85
                    };
86
                    fetcher.setSelTransf(transf);
87
                    final List<SQLRowValues> fetched = fetcher.fetch();
88
                    if (fetched.size() > 1)
89
                        throw new IllegalStateException("more than one row fetched for " + this + " with " + fetcher.getReq() + " :\n" + fetched);
17 ilm 90
 
80 ilm 91
                    // OK if lastReferentField != null : a referent row has been deleted
92
                    if (fetched.size() == 0 && lastReferentField == null) {
93
                        Log.get().fine("no row fetched for " + this + ", lines have been changed without the TableModel knowing : " + lines + " req :\n" + fetcher.getReq());
94
                        getModel().updateAll();
95
                    } else {
96
                        final SQLRowValues soleFetched = CollectionUtils.getSole(fetched);
97
                        // copy it to each affected lines
98
                        for (final ListSQLLine line : lines) {
99
                            line.loadAt(getID(), soleFetched, p);
100
                        }
17 ilm 101
                    }
102
                }
103
            }
104
        }
105
    }
106
 
107
    protected abstract Collection<String> getModifedFields();
108
}