All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.efaps.admin.datamodel.SQLTable Maven / Gradle / Ivy

Go to download

eFaps is a framework used to map objects with or without attached files to a relational database and optional file systems (only for attaches files). Configurable access control can be provided down to object and attribute level depending on implementation and use case. Depending on requirements, events (like triggers) allow to implement business logic and to separate business logic from user interface. The framework includes integrations (e.g. webdav, full text search) and a web application as 'simple' configurable user interface. Some best practises, example web application modules (e.g. team work module) support administrators and implementers using this framework.

The newest version!
/*
 * Copyright 2003 - 2013 The eFaps Team
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Revision:        $Rev$
 * Last Changed:    $Date$
 * Last Changed By: $Author$
 */

package org.efaps.admin.datamodel;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;

import org.efaps.db.Context;
import org.efaps.db.databases.information.TableInformation;
import org.efaps.db.transaction.ConnectionResource;
import org.efaps.db.wrapper.SQLPart;
import org.efaps.db.wrapper.SQLSelect;
import org.efaps.util.EFapsException;
import org.efaps.util.cache.CacheLogListener;
import org.efaps.util.cache.CacheReloadException;
import org.efaps.util.cache.InfinispanCache;
import org.infinispan.Cache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This is the class for the table description. The table description holds
 * information in which table attributes are stored.
 *
 * @author The eFaps Team
 * @version $Id$
 */
public final class SQLTable
    extends AbstractDataModelObject
{
    /**
     * Needed for serialization.
     */
    private static final long serialVersionUID = 1L;

    /**
     * Logging instance used in this class.
     */
    private static final Logger LOG = LoggerFactory.getLogger(SQLTable.class);

    /**
     * This is the SQL select statement to select a role from the database by
     * ID.
     */
    private static final String SQL_ID = new SQLSelect()
                    .column("ID")
                    .column("UUID")
                    .column("NAME")
                    .column("SQLTABLE")
                    .column("SQLCOLUMNID")
                    .column("SQLCOLUMNTYPE")
                    .column("DMTABLEMAIN")
                    .from("V_ADMINSQLTABLE", 0)
                    .addPart(SQLPart.WHERE).addColumnPart(0, "ID").addPart(SQLPart.EQUAL).addValuePart("?").toString();

    /**
     * This is the SQL select statement to select a role from the database by
     * Name.
     */
    private static final String SQL_NAME = new SQLSelect()
                    .column("ID")
                    .column("UUID")
                    .column("NAME")
                    .column("SQLTABLE")
                    .column("SQLCOLUMNID")
                    .column("SQLCOLUMNTYPE")
                    .column("DMTABLEMAIN")
                    .from("V_ADMINSQLTABLE", 0)
                    .addPart(SQLPart.WHERE).addColumnPart(0, "NAME").addPart(SQLPart.EQUAL).addValuePart("?")
                    .toString();

    /**
     * This is the SQL select statement to select a role from the database by
     * UUID.
     */
    private static final String SQL_UUID = new SQLSelect()
                    .column("ID")
                    .column("UUID")
                    .column("NAME")
                    .column("SQLTABLE")
                    .column("SQLCOLUMNID")
                    .column("SQLCOLUMNTYPE")
                    .column("DMTABLEMAIN")
                    .from("V_ADMINSQLTABLE", 0)
                    .addPart(SQLPart.WHERE).addColumnPart(0, "UUID").addPart(SQLPart.EQUAL).addValuePart("?")
                    .toString();

    /**
     * Name of the Cache by UUID.
     */
    private static final String UUIDCACHE = SQLTable.class.getName() + ".UUID";

    /**
     * Name of the Cache by ID.
     */
    private static final String IDCACHE =  SQLTable.class.getName() + ".ID";

    /**
     * Name of the Cache by Name.
     */
    private static final String NAMECACHE =  SQLTable.class.getName() + ".Name";

    /**
     * Instance variable for the name of the SQL table.
     *
     * @see #getSqlTable
     */
    private final String sqlTable;

    /**
     * This instance variable stores the SQL column name of the id of a table.
     *
     * @see #getSqlColId
     */
    private final String sqlColId;

    /**
     * The instance variable stores the SQL column name of the type id.
     *
     * @see #getSqlColType
     */
    private final String sqlColType;

    /**
     * Stores the information about the SQL table within the database.
     *
     * @see #getTableInformation
     */
    private final TableInformation tableInformation;

    /**
     * The instance variable stores the main table for this table instance. The
     * main table is the table, which holds the information about the SQL select
     * statement to get a new id. Also the main table must be inserted as first
     * insert (e.g. the id in the table with a main table has a foreign key to
     * the id of the main table).
     *
     * @see #getMainTable()
     */
    private SQLTable mainTable = null;

    /**
     * The instance variable stores all types which stores information in this
     * table.
     *
     * @see #getTypes()
     */
    private final Set types = new HashSet();

    /**
     * The instance variables is set to true if this table is only a read
     * only SQL table. This means, that no insert and no update on this table is
     * allowed and made.
     *
     * @see #isReadOnly()
     */
    private boolean readOnly = false;

    /**
     * This is the constructor for class {@link Attribute}. Every instance of
     * class {@link Attribute} must have a name (parameter _name) and an
     * identifier (parameter _id).
     *
     * @param _con Connection
     * @param _id eFaps id of the SQL table
     * @param _uuid unique identifier
     * @param _name eFaps name of the SQL table
     * @param _sqlTable name of the SQL Table in the database
     * @param _sqlColId name of column for the id within SQL table
     * @param _sqlColType name of column for the type within SQL table
     * @throws SQLException on error
     */
    private SQLTable(final Connection _con,
                     final long _id,
                     final String _uuid,
                     final String _name,
                     final String _sqlTable,
                     final String _sqlColId,
                     final String _sqlColType)
        throws SQLException
    {
        super(_id, _uuid, _name);
        this.sqlTable = _sqlTable.trim();
        this.sqlColId = _sqlColId.trim();
        this.sqlColType = (_sqlColType != null) ? _sqlColType.trim() : null;
        this.tableInformation = Context.getDbType().getCachedTableInformation(this.sqlTable);
    }

    /**
     * The instance method adds a new type to the type list.
     *
     * @param _typeId id of the Type to add
     * @see #types
     */
    protected void addType(final Long _typeId)
    {
        if (!this.types.contains(_typeId)) {
            this.types.add(_typeId);
            setDirty();
        }
    }

    /**
     * The instance method sets a new property value.
     *
     * @param _name name of the property
     * @param _value value of the property
     * @throws CacheReloadException on error
     */
    @Override
    protected void setProperty(final String _name,
                               final String _value)
        throws CacheReloadException
    {
        if (_name.equals("ReadOnly")) {
            this.readOnly = "true".equalsIgnoreCase("true");
        }
    }

    /**
     * This is the getter method for instance variable {@link #sqlTable}.
     *
     * @return value of instance variable {@link #sqlTable}
     * @see #sqlTable
     */
    public String getSqlTable()
    {
        return this.sqlTable;
    }

    /**
     * This is the getter method for instance variable {@link #sqlColId}.
     *
     * @return value of instance variable {@link #sqlColId}
     * @see #sqlColId
     */
    public String getSqlColId()
    {
        return this.sqlColId;
    }

    /**
     * This is the getter method for instance variable {@link #sqlColType}.
     *
     * @return value of instance variable {@link #sqlColType}
     * @see #sqlColType
     */
    public String getSqlColType()
    {
        return this.sqlColType;
    }

    /**
     * This is the getter method for instance variable {@link #tableInformation}
     * .
     *
     * @return value of instance variable {@link #tableInformation}
     * @see #tableInformation
     */
    public TableInformation getTableInformation()
    {
        return this.tableInformation;
    }

    /**
     * This is the getter method for instance variable {@link #mainTable}.
     *
     * @return value of instance variable {@link #mainTable}
     * @see #mainTable
     */
    public SQLTable getMainTable()
    {
        return this.mainTable;
    }

    /**
     * This is the getter method for instance variable {@link #types}.
     *
     * @return value of instance variable {@link #types}
     * @see #types
     * @throws CacheReloadException on error
     */
    public Set getTypes()
        throws CacheReloadException
    {
        final Set ret = new HashSet();
        for (final Long id : this.types) {
            ret.add(Type.get(id));
        }
        return Collections.unmodifiableSet(ret);
    }

    /**
     * This is the getter method for instance variable {@link #readOnly}.
     *
     * @return value of instance variable {@link #readOnly}
     * @see #readOnly
     */
    public boolean isReadOnly()
    {
        return this.readOnly;
    }

    @Override
    public boolean equals(final Object _obj)
    {
        boolean ret;
        if (_obj instanceof SQLTable) {
            ret = ((SQLTable) _obj).getId() == getId();
        } else {
            ret = super.equals(_obj);
        }
        return ret;
    }

    @Override
    public int hashCode()
    {
        return  Long.valueOf(getId()).intValue();
    }

    /**
     * Method to initialize the Cache of this CacheObjectInterface.
     *
     * @param _class Clas that started the initialization
     */
    public static void initialize(final Class _class)
    {
        if (InfinispanCache.get().exists(SQLTable.UUIDCACHE)) {
            InfinispanCache.get().getCache(SQLTable.UUIDCACHE).clear();
        } else {
            InfinispanCache.get().getCache(SQLTable.UUIDCACHE)
                            .addListener(new CacheLogListener(SQLTable.LOG));
        }
        if (InfinispanCache.get().exists(SQLTable.IDCACHE)) {
            InfinispanCache.get().getCache(SQLTable.IDCACHE).clear();
        } else {
            InfinispanCache.get().getCache(SQLTable.IDCACHE)
                            .addListener(new CacheLogListener(SQLTable.LOG));
        }
        if (InfinispanCache.get().exists(SQLTable.NAMECACHE)) {
            InfinispanCache.get().getCache(SQLTable.NAMECACHE).clear();
        } else {
            InfinispanCache.get().getCache(SQLTable.NAMECACHE)
                            .addListener(new CacheLogListener(SQLTable.LOG));
        }
    }

    /**
     * Method to initialize the Cache of this CacheObjectInterface.
     */
    public static void initialize()
    {
        SQLTable.initialize(SQLTable.class);
    }

    /**
     * Returns for given parameter _id the instance of class
     * {@link SQLTable}.
     *
     * @param _id id to search in the cache
     * @return instance of class {@link SQLTable}
     * @throws CacheReloadException on error
     * @see #getCache
     */
    public static SQLTable get(final long _id)
        throws CacheReloadException
    {
        final Cache cache = InfinispanCache.get().getCache(SQLTable.IDCACHE);
        if (!cache.containsKey(_id)) {
            SQLTable.getSQLTableFromDB(SQLTable.SQL_ID, _id);
        }
        return cache.get(_id);
    }

    /**
     * Returns for given parameter _name the instance of class
     * {@link SQLTable}.
     *
     * @param _name name to search in the cache
     * @return instance of class {@link SQLTable}
     * @throws CacheReloadException on error
     * @see #getCache
     */
    public static SQLTable get(final String _name)
        throws CacheReloadException
    {
        final Cache cache = InfinispanCache.get().getCache(SQLTable.NAMECACHE);
        if (!cache.containsKey(_name)) {
            SQLTable.getSQLTableFromDB(SQLTable.SQL_NAME, _name);
        }
        return cache.get(_name);
    }

    /**
     * Returns for given parameter _uuid the instance of class
     * {@link SQLTable}.
     *
     * @param _uuid UUID the tanel is wanted for
     * @return instance of class {@link Type}
     * @throws CacheReloadException on error
     */
    public static SQLTable get(final UUID _uuid)
        throws CacheReloadException
    {
        final Cache cache = InfinispanCache.get().getCache(SQLTable.UUIDCACHE);
        if (!cache.containsKey(_uuid)) {
            SQLTable.getSQLTableFromDB(SQLTable.SQL_UUID, String.valueOf(_uuid));
        }
        return cache.get(_uuid);
    }

    /**
     * @param _sqlTable SQLTable to be cached
     */
    private static void cacheSQLTable(final SQLTable _sqlTable)
    {
        final Cache cache4UUID = InfinispanCache.get().getIgnReCache(
                        SQLTable.UUIDCACHE);
        cache4UUID.putIfAbsent(_sqlTable.getUUID(), _sqlTable);

        final Cache nameCache = InfinispanCache.get().getIgnReCache(
                        SQLTable.NAMECACHE);
        nameCache.putIfAbsent(_sqlTable.getName(), _sqlTable);
        final Cache idCache = InfinispanCache.get().getIgnReCache(
                        SQLTable.IDCACHE);
        idCache.putIfAbsent(_sqlTable.getId(), _sqlTable);
    }

    /**
     * @param _sql      SQL Statement to be executed
     * @param _criteria filter criteria
     * @return true if successful
     * @throws CacheReloadException on error
     */
    private static boolean getSQLTableFromDB(final String _sql,
                                             final Object _criteria)
        throws CacheReloadException
    {
        final boolean ret = false;
        ConnectionResource con = null;
        try {
            SQLTable table = null;
            long tableMainId = 0;
            con = Context.getThreadContext().getConnectionResource();
            PreparedStatement stmt = null;
            try {
                stmt = con.getConnection().prepareStatement(_sql);
                stmt.setObject(1, _criteria);
                final ResultSet rs = stmt.executeQuery();
                if (rs.next()) {
                    final long id = rs.getLong(1);
                    final String name = rs.getString(3).trim();
                    table = new SQLTable(con.getConnection(),
                                    id,
                                    rs.getString(2),
                                    name,
                                    rs.getString(4),
                                    rs.getString(5),
                                    rs.getString(6));
                    tableMainId = rs.getLong(7);
                    SQLTable.cacheSQLTable(table);
                    SQLTable.LOG.debug("read SQLTable '{}' (id = {}))", name, id);
                }
                rs.close();
            } finally {
                if (stmt != null) {
                    stmt.close();
                }
            }
            con.commit();
            if (table != null) {
                table.readFromDB4Properties();
                if (tableMainId > 0) {
                    final SQLTable mainTable = SQLTable.get(tableMainId);
                    table.mainTable = mainTable;
                }
                // needed due to cluster serialization that does not update automatically
                SQLTable.cacheSQLTable(table);
            }
        } catch (final SQLException e) {
            throw new CacheReloadException("could not read sql tables", e);
        } catch (final EFapsException e) {
            throw new CacheReloadException("could not read sql tables", e);
        } finally {
            if ((con != null) && con.isOpened()) {
                try {
                    con.abort();
                } catch (final EFapsException e) {
                    throw new CacheReloadException("could not read sql tables", e);
                }
            }
        }
        return ret;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy