OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 19 | Go to most recent revision | Details | 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.element;
15
 
16
import org.openconcerto.sql.Log;
17
import org.openconcerto.sql.model.DBStructureItemNotFound;
18
import org.openconcerto.sql.model.SQLName;
19
import org.openconcerto.sql.model.SQLTable;
20
import org.openconcerto.utils.CollectionMap;
21
import org.openconcerto.utils.CollectionUtils;
22
import org.openconcerto.utils.cc.ITransformer;
23
 
24
import java.lang.reflect.InvocationTargetException;
25
import java.util.Collection;
26
import java.util.HashMap;
27
import java.util.HashSet;
28
import java.util.Map;
29
import java.util.Set;
30
 
31
/**
32
 * Directory of SQLElement by table.
33
 *
34
 * @author Sylvain CUAZ
35
 */
36
public final class SQLElementDirectory {
37
 
38
    private final Map<SQLTable, SQLElement> elements;
39
    private final CollectionMap<String, SQLTable> tableNames;
40
    private final CollectionMap<Class<? extends SQLElement>, SQLTable> byClass;
41
 
42
    public SQLElementDirectory() {
43
        this.elements = new HashMap<SQLTable, SQLElement>();
44
        // to mimic elements behaviour, if we add twice the same table
45
        // the second one should replace the first one
46
        this.tableNames = new CollectionMap<String, SQLTable>(HashSet.class);
47
        this.byClass = new CollectionMap<Class<? extends SQLElement>, SQLTable>(HashSet.class);
48
    }
49
 
50
    private static <K> SQLTable getSoleTable(CollectionMap<K, SQLTable> m, K key) throws IllegalArgumentException {
51
        final Collection<SQLTable> res = m.getNonNull(key);
52
        if (res.size() > 1)
53
            throw new IllegalArgumentException(key + " is not unique: " + CollectionUtils.join(res, ",", new ITransformer<SQLTable, SQLName>() {
54
                @Override
55
                public SQLName transformChecked(SQLTable input) {
56
                    return input.getSQLName();
57
                }
58
            }));
59
        return CollectionUtils.getSole(res);
60
    }
61
 
62
    public synchronized final void putAll(SQLElementDirectory o) {
63
        for (final SQLElement elem : o.getElements()) {
64
            if (!this.contains(elem.getTable()))
65
                this.addSQLElement(elem);
66
        }
67
    }
68
 
69
    /**
70
     * Add an element by creating it with the no-arg constructor. If the element cannot find its
71
     * table and thus raise DBStructureItemNotFound, the exception is logged.
72
     *
73
     * @param element the element to add.
74
     */
75
    public final void addSQLElement(final Class<? extends SQLElement> element) {
76
        try {
77
            this.addSQLElement(element.getConstructor().newInstance());
78
        } catch (InvocationTargetException e) {
79
            if (e.getCause() instanceof DBStructureItemNotFound) {
80
                Log.get().config("ignore inexistent tables: " + e.getCause().getLocalizedMessage());
81
                return;
82
            }
83
            throw new IllegalArgumentException("ctor failed", e);
84
        } catch (Exception e) {
85
            throw new IllegalArgumentException("no-arg ctor failed", e);
86
        }
87
    }
88
 
89
    /**
90
     * Adds an already instantiated element.
91
     *
92
     * @param elem the SQLElement to add.
93
     */
94
    public synchronized final void addSQLElement(SQLElement elem) {
95
        this.elements.put(elem.getTable(), elem);
96
        this.tableNames.put(elem.getTable().getName(), elem.getTable());
97
        this.byClass.put(elem.getClass(), elem.getTable());
98
    }
99
 
100
    public synchronized final boolean contains(SQLTable t) {
101
        return this.elements.containsKey(t);
102
    }
103
 
104
    public synchronized final SQLElement getElement(SQLTable t) {
105
        return this.elements.get(t);
106
    }
107
 
108
    /**
109
     * Search for a table whose name is <code>tableName</code>.
110
     *
111
     * @param tableName a table name, e.g. "ADRESSE".
112
     * @return the corresponding SQLElement, or <code>null</code> if there is no table named
113
     *         <code>tableName</code>.
114
     * @throws IllegalArgumentException if more than one table match.
115
     */
116
    public final SQLElement getElement(String tableName) {
117
        return this.getElement(getSoleTable(this.tableNames, tableName));
118
    }
119
 
120
    /**
121
     * Search for an SQLElement whose class is <code>clazz</code>.
122
     *
123
     * @param <S> type of SQLElement
124
     * @param clazz the class.
125
     * @return the corresponding SQLElement, or <code>null</code> if none can be found.
126
     * @throws IllegalArgumentException if there's more than one match.
127
     */
128
    public final <S extends SQLElement> S getElement(Class<S> clazz) {
129
        return clazz.cast(this.getElement(getSoleTable(this.byClass, clazz)));
130
    }
131
 
132
    public synchronized final Set<SQLTable> getTables() {
133
        return this.elements.keySet();
134
    }
135
 
136
    public synchronized final Collection<SQLElement> getElements() {
137
        return this.elements.values();
138
    }
139
}