OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 156 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 2011 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.task.config;

import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.PropsConfiguration;
import org.openconcerto.sql.element.ConfSQLElement;
import org.openconcerto.sql.element.SQLElementDirectory;
import org.openconcerto.sql.model.DBRoot;
import org.openconcerto.sql.model.DBSystemRoot;
import org.openconcerto.sql.model.SQLBase;
import org.openconcerto.sql.model.SQLDataSource;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLFilter;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.SQLTableEvent;
import org.openconcerto.sql.model.SQLTableModifiedListener;
import org.openconcerto.sql.users.UserCommonSQLElement;
import org.openconcerto.sql.users.rights.RightSQLElement;
import org.openconcerto.sql.users.rights.UserRightSQLElement;
import org.openconcerto.task.TM;
import org.openconcerto.task.element.CompanyAccessSQLElement;
import org.openconcerto.task.element.TaskRightSQLElement;
import org.openconcerto.task.element.TaskSQLElement;
import org.openconcerto.utils.BaseDirs;
import org.openconcerto.utils.DesktopEnvironment;
import org.openconcerto.utils.LogUtils;
import org.openconcerto.utils.ProductInfo;
import org.openconcerto.utils.i18n.Grammar_fr;
import org.openconcerto.utils.i18n.NounClass;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Properties;

import net.jcip.annotations.GuardedBy;

public abstract class ComptaBasePropsConfiguration extends PropsConfiguration {

    public abstract void setUpSocieteDataBaseConnexion(int base);

    public static File getConfFile(final ProductInfo info) {
        final String confFilePath = System.getProperty("gestion.confFile");
        final File wdFile = new File("Configuration", "main.properties");
        final File confFile;
        if (confFilePath != null) {
            confFile = new File(confFilePath);
        } else if (wdFile.isFile()) {
            confFile = wdFile;
        } else {
            // we added organisation name, so migrate preferences
            final File prefsFolder = BaseDirs.create(info).getPreferencesFolder();
            if (!prefsFolder.exists()) {
                try {
                    final File oldDir = DesktopEnvironment.getDE().getPreferencesFolder(info.getName());
                    Configuration.migrateToNewDir(oldDir, prefsFolder);
                } catch (IOException ex) {
                    throw new IllegalStateException("Couldn't migrate preferences dir", ex);
                }
            }
            confFile = new File(prefsFolder, "main.properties");
        }
        return confFile;
    }

    public static InputStream getStreamStatic(final String name) {
        InputStream stream = ((PropsConfiguration) Configuration.getInstance()).getStream(name);

        // FIXME Checker ailleurs ou throws filenotfoundexception

        // if (stream == null) {
        //
        // JOptionPane.showMessageDialog(null, "Impossible de trouver le fichier " + name);
        // }
        return stream;
    }

    public static InputStream getStream(final String name, final String... dirs) throws FileNotFoundException {
        InputStream res = null;
        for (final String dir : dirs) {
            // getResourceAsStream() doesn't handle dir//file
            res = getStreamStatic(dir + (dir.endsWith("/") ? "" : "/") + name);
            if (res != null)
                return res;
        }
        throw new FileNotFoundException(name + " not found in " + Arrays.asList(dirs));
    }

    @GuardedBy("this")
    private SQLRow rowSociete = null;
    private final SQLTableModifiedListener rowSocieteListener = (evt) -> updateRowSociete(evt);
    @GuardedBy("this")
    private DBRoot baseSociete;

    {
        // * logs
        LogUtils.rmRootHandlers();
        LogUtils.setUpConsoleHandler();
        this.setLoggersLevel();
    }

    public ComptaBasePropsConfiguration(Properties props, final ProductInfo productInfo) {
        super(props);

        this.setProductInfo(productInfo);
        // don't overwrite (allow to map no roots, just to test connection)
        if (getProperty("systemRoot.rootsToMap") == null) {
            final String interAppRootName = getInterAppRootName();
            this.setProperty("systemRoot.rootsToMap", interAppRootName);
            this.setProperty("systemRoot.rootPath", interAppRootName);
        }
    }

    @Override
    public void destroy() {
        this.setRowSociete(null);
        super.destroy();
    }

    public final String getInterAppRootName() {
        String name = "ilm";
        return name + "_Common";
    }


    // use Configuration directory if it exists
    @Override
    protected FileMode getFileMode() {
        return FileMode.NORMAL_FILE;
    }

    @Override
    protected void initDS(SQLDataSource ds) {
        super.initDS(ds);
        // Old H2 versions need this to safely open page store files
        // (https://github.com/h2database/h2database/issues/1023), and new version ignore it
        // (https://github.com/h2database/h2database/pull/1208).
        ds.addConnectionProperty("MVCC", "false");
        // Don't begin transition from page store just yet.
        ds.addConnectionProperty("MV_STORE", "false");
    }

    @Override
    protected List<String> getMappings() {
        final List<String> res = new ArrayList<>(super.getMappings());
        final String pkg = "/" + TM.class.getPackage().getName().replace('.', '/');
        res.add(pkg + "/translation/SQLElementNames");
        return res;
    }

    @Override
    protected SQLElementDirectory createDirectory() {
        final SQLElementDirectory dir = super.createDirectory();

        // TACHE_COMMON points to SOCIETE but we never display it we don't need the full element
        dir.addSQLElement(new ConfSQLElement("SOCIETE_COMMON", Grammar_fr.getInstance().createPhrase(NounClass.FEMININE, "société")));
        dir.addSQLElement(new ConfSQLElement("EXERCICE_COMMON", Grammar_fr.getInstance().createPhrase(NounClass.MASCULINE, "exercice")));
        dir.addSQLElement(new ConfSQLElement("ADRESSE_COMMON", Grammar_fr.getInstance().createPhrase(NounClass.FEMININE, "adresse")));

        dir.addSQLElement(new TaskRightSQLElement());
        dir.addSQLElement(new TaskSQLElement());

        dir.addSQLElement(new UserCommonSQLElement(getRoot(), false));
        dir.addSQLElement(new CompanyAccessSQLElement());
        dir.addSQLElement(new UserRightSQLElement(getRoot()));
        dir.addSQLElement(new RightSQLElement(getRoot()));

        return dir;
    }

    @Override
    protected SQLFilter createFilter() {
        // we don't use the filter so remove everything
        return new SQLFilter(getDirectory(), getSystemRoot().getGraph().cloneForFilterKeep(Collections.<SQLField> emptySet()));
    }

    public final String getSocieteBaseName() {
        return getRowSociete().getString("DATABASE_NAME");
    }

    public synchronized final SQLRow getRowSociete() {
        return this.rowSociete;
    }

    public final int getSocieteID() {
        final SQLRow row = this.getRowSociete();
        return row == null ? SQLRow.NONEXISTANT_ID : row.getID();
    }

    private synchronized void updateRowSociete(SQLTableEvent evt) {
        if (evt.getRow().equals(this.rowSociete)) {
            this.rowSociete.fetchValues();
        }
    }

    public final SQLTable getSocieteTable() {
        return getSocieteTable(true);
    }

    protected final SQLTable getSocieteTable(final boolean mustExist) {
        return getSystemRoot().findTable("SOCIETE_COMMON", mustExist);
    }

    // undefined ID is allowed (used for the template root)
    protected final void setRowSociete(Number id) {
        final boolean clear = id == null;
        final SQLRow row;
        final SQLTable tableSociete = getSocieteTable(!clear);
        if (clear) {
            row = null;
            // might be null if mapsToRoot is empty (e.g. tests)
            if (tableSociete != null)
                tableSociete.removeTableModifiedListener(this.rowSocieteListener);
        } else {
            row = tableSociete.getRow(id.intValue());
            if (row == null) {
                throw new IllegalArgumentException("no row for id " + id + " in " + tableSociete);
            } else if (!row.isValid()) {
                throw new IllegalArgumentException("invalid row : " + row);
            }
            tableSociete.addTableModifiedListener(this.rowSocieteListener);
        }
        synchronized (this) {
            this.rowSociete = row;
        }
    }

    @Deprecated
    public final SQLBase getSQLBaseSociete() {
        return this.getRootSociete().getBase();
    }

    public final DBRoot getRootSociete() {
        return this.getRootSociete(true);
    }

    protected synchronized final DBRoot getRootSociete(final boolean create) {
        if (create && this.baseSociete == null && this.getRowSociete() != null)
            this.baseSociete = this.createSQLBaseSociete();
        return this.baseSociete;
    }

    private DBRoot createSQLBaseSociete() {
        final DBSystemRoot b = this.getSystemRoot();
        // now map the societe
        final String societeBaseName = this.getSocieteBaseName();
        b.addRootToMap(societeBaseName);
        try {
            b.reload(Collections.singleton(societeBaseName));
        } catch (SQLException e) {
            throw new IllegalStateException("could not access societe base", e);
        }
        b.prependToRootPath(societeBaseName);
        return b.getRoot(societeBaseName);
    }

}