
org.efaps.admin.datamodel.Attribute Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of efaps-kernel Show documentation
Show all versions of efaps-kernel Show documentation
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 - 2014 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.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.UUID;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.efaps.admin.event.EventDefinition;
import org.efaps.admin.event.EventType;
import org.efaps.admin.event.Parameter.ParameterValues;
import org.efaps.admin.event.Return;
import org.efaps.admin.event.Return.ReturnValues;
import org.efaps.ci.CIAdminDataModel;
import org.efaps.ci.CIAdminUser;
import org.efaps.db.Context;
import org.efaps.db.databases.information.ColumnInformation;
import org.efaps.db.transaction.ConnectionResource;
import org.efaps.db.wrapper.SQLInsert;
import org.efaps.db.wrapper.SQLPart;
import org.efaps.db.wrapper.SQLSelect;
import org.efaps.db.wrapper.SQLUpdate;
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 attribute description. The type description holds
* information about creation of a new instance of a attribute with default
* values.
*
* @author The eFaps Team
* @version $Id$
*/
public class Attribute
extends AbstractDataModelObject
{
/**
* ENUM used to access the different attribute types.
*/
public enum AttributeTypeDef
{
/** Attribute type Link. */
ATTRTYPE_LINK("440f472f-7be2-41d3-baec-4a2f0e4e5b31"),
/** Attribute type Link with Ranges. */
ATTRTYPE_LINK_WITH_RANGES("9d6b2e3e-68ce-4509-a5f0-eae42323a696"),
/** Attribute type PersonLink. */
ATTRTYPE_GROUP_LINK("a48538dd-5d9b-468f-a84f-bf42791eed66"),
/** Attribute type PersonLink. */
ATTRTYPE_PERSON_LINK("7b8f98de-1967-44e0-b174-027349868a61"),
/** Attribute type Creator Link. */
ATTRTYPE_CREATOR_LINK("76122fe9-8fde-4dd4-a229-e48af0fb4083"),
/** Attribute type Modifier Link. */
ATTRTYPE_MODIFIER_LINK("447a7c87-8395-48c4-b2ed-d4e96d46332c"),
/** Attribute type Multi Line Array. */
ATTRTYPE_MULTILINEARRAY("adb13c3d-9506-4da2-8d75-b54c76779c6c"),
/** Attribute type Status. */
ATTRTYPE_STATUS("0161bcdb-45e9-4839-a709-3a1c56f8a76a"),
/** Attribute type Enum. */
ATTRTYPE_ENUM("b7c6a324-5dec-425f-b778-fa8fabf80202"),
/** Attribute type BitEnum. */
ATTRTYPE_BITENUM("a9b1abde-d58d-4aea-8cdc-f2870111f1cd"),
/** Attribute type BitEnum. */
ATTRTYPE_JAXB("58817bd8-db76-4b40-8acd-18112fe96170");
/**
* Stored the UUID for the given type.
*/
private final UUID uuid;
/**
* Private Constructor.
*
* @param _uuid UUID to set
*/
private AttributeTypeDef(final String _uuid)
{
this.uuid = UUID.fromString(_uuid);
}
/**
* @return the uuid
*/
public UUID getUuid()
{
return this.uuid;
}
}
/**
* Needed for serialization.
*/
private static final long serialVersionUID = 1L;
/**
* Logging instance used in this class.
*/
private static final Logger LOG = LoggerFactory.getLogger(Attribute.class);
/**
* SQL Statement to get attributes for at type.
*/
private static final String SQL_TYPE = new SQLSelect()
.column("ID")
.column("NAME")
.column("TYPEID")
.column("DMTABLE")
.column("DMATTRIBUTETYPE")
.column("DMTYPELINK")
.column("PARENTSET")
.column("SQLCOLUMN")
.column("DEFAULTVAL")
.column("DIMENSION")
.column("CLASSNAME")
.from("V_ADMINATTRIBUTE", 0)
.addPart(SQLPart.WHERE).addColumnPart(0, "DMTYPE").addPart(SQLPart.EQUAL).addValuePart("?")
.toString();
/**
* SQL Statement to get an attribute.
*/
private static final String SQL_ATTR = new SQLSelect()
.column("DMTYPE")
.from("V_ADMINATTRIBUTE", 0)
.addPart(SQLPart.WHERE).addColumnPart(0, "ID").addPart(SQLPart.EQUAL).addValuePart("?").toString();
/**
* Name of the Cache by Name.
*/
private static String NAMECACHE = Attribute.class.getName() + ".Name";
/**
* Name of the Cache by ID.
*/
private static String IDCACHE = Attribute.class.getName() + ".ID";
/**
* This is the instance variable for the table, where attribute is stored.
*
* @see #getTable
*/
private final SQLTable sqlTable;
/**
* Instance variable for the link to another type id..
*
* @see #getLink
* @see #setLink
*/
private Long link = null;
/**
* Instance variable for the parent type id.
*
* @see #getParent
* @see #setParent
*/
private final Long parent;
/**
* This instance variable stores the sql column name.
*
* @see #getSqlColName
* @see #setSqlColName
*/
private final ArrayList sqlColNames = new ArrayList();
/**
* The instance variable stores the attribute type for this attribute.
*
* @see #getAttributeType
*/
private final AttributeType attributeType;
/**
* The String holds the default value as string for this Attribute.
*
* @see #getDefaultValue
*/
private final String defaultValue;
/**
* Is the attribute required? This means at minimum one part of the
* attribute is not allowed to be a null value.
*
* @see #isRequired
*/
private final boolean required;
/**
* The parent this attribute belongs to.
*/
private AttributeSet parentSet;
/**
* Size of the attribute (for string). Precision of the attribute (for
* decimal).
*/
private final int size;
/**
* Scale of the attribute (for decimal).
*/
private final int scale;
/**
* UUID of the dimension belonging to this attribute.
*/
private final String dimensionUUID;
/**
* Holds the Attributes this Attribute depend on. A TreeMap is used to have
* a fixed position of each attribute. (Needed e.g for printquery)
*/
private Map dependencies;
/**
* Key of this Attribute. Consist of name of the Parent Type and name of the Attribute itself
*/
private String key;
/**
* ClassName of this Attribute. Used only in case of
* {@link org.efaps.admin.datamodel.attributetype.EnumType}
* and
* {@link org.efaps.admin.datamodel.attributetype.BitEnumType}.
*/
private String className;
/**
* 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 _id id of the attribute
* @param _parentId id of the parent type
* @param _name name of the instance
* @param _sqlColNames name of the SQL columns
* @param _sqlTable table of this attribute
* @param _attributeType type of this attribute
* @param _defaultValue default value for this attribute
* @param _dimensionUUID UUID of the Dimension
* @throws EFapsException on error while retrieving column information from
* database
*/
//CHECKSTYLE:OFF
protected Attribute(final long _id,
final long _parentId,
final String _name,
final String _sqlColNames,
final SQLTable _sqlTable,
final AttributeType _attributeType,
final String _defaultValue,
final String _dimensionUUID)
//CHECKSTYLE:ON
throws EFapsException
{
super(_id, null, _name);
this.sqlTable = _sqlTable;
this.parent = _parentId;
this.attributeType = _attributeType;
this.defaultValue = (_defaultValue != null) ? _defaultValue.trim() : null;
this.dimensionUUID = (_dimensionUUID != null) ? _dimensionUUID.trim() : null;
// add SQL columns and evaluate if attribute is required
boolean req = false;
int sizeTemp = 0;
int scaleTemp = 0;
final StringTokenizer tok = new StringTokenizer(_sqlColNames.trim(), ",");
while (tok.hasMoreTokens()) {
final String colName = tok.nextToken().trim();
getSqlColNames().add(colName);
final ColumnInformation columInfo = this.sqlTable.getTableInformation().getColInfo(colName);
if (columInfo == null) {
throw new EFapsException(Attribute.class, "Attribute", _id, _name, _sqlTable, colName);
}
req |= !columInfo.isNullable();
sizeTemp = columInfo.getSize();
scaleTemp = columInfo.getScale();
}
this.size = sizeTemp;
this.scale = scaleTemp;
this.required = req;
}
/**
* 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).
* This constructor is used for the copy method (clone of an attribute
* instance).
*
* @see #copy
* @param _id id of the attribute
* @param _name name of the instance
* @param _sqlTable table of this attribute
* @param _attributeType typer of this attribute
* @param _defaultValue default value for this attribute
* @param _dimensionUUID uuid of the dimension belnging to this attribute
* @param _required is it required
* @param _size Size
* @param _scale Scale
*/
// CHECKSTYLE:OFF
private Attribute(final long _id,
final long _parentId,
final String _name,
final SQLTable _sqlTable,
final AttributeType _attributeType,
final String _defaultValue,
final String _dimensionUUID,
final boolean _required,
final int _size,
final int _scale)
{
// CHECKSTYLE:ON
super(_id, null, _name);
this.parent = _parentId;
this.sqlTable = _sqlTable;
this.attributeType = _attributeType;
this.defaultValue = (_defaultValue != null) ? _defaultValue.trim() : null;
this.required = _required;
this.size = _size;
this.scale = _scale;
this.dimensionUUID = _dimensionUUID;
}
/**
* This method returns true if a link exists. This is made with a
* test of the return value of method {@link #getLink} on null.
*
* @return true if this attribute has a link, otherwise false
*/
public boolean hasLink()
{
return this.link != null;
}
/**
* The method makes a clone of the current attribute instance.
* @param _parentId if of the parent type
* @return clone of current attribute instance
*/
protected Attribute copy(final long _parentId)
{
final Attribute ret = new Attribute(getId(), _parentId, getName(), this.sqlTable, this.attributeType,
this.defaultValue, this.dimensionUUID, this.required, this.size, this.scale);
ret.getSqlColNames().addAll(getSqlColNames());
ret.setLink(this.link);
ret.setClassName(getClassName());
ret.getProperties().putAll(getProperties());
return ret;
}
/**
* {@inheritDoc}
*/
@Override
public void addEvent(final EventType _eventtype,
final EventDefinition _eventdef)
throws CacheReloadException
{
super.addEvent(_eventtype, _eventdef);
for (final Type child : getParent().getChildTypes()) {
final Attribute childAttr = child.getAttribute(getName());
if (childAttr != null) {
childAttr.addEvent(_eventtype, _eventdef);
}
}
}
/**
* This is the getter method for instance variable {@link #sqlTable}.
*
* @return value of instance variable {@link #sqlTable}
* @see #sqlTable
*/
public SQLTable getTable()
{
return this.sqlTable;
}
/**
* This is the setter method for instance variable {@link #link}.
*
* @param _link new instance of class {@link Long} to set for link
* @see #link
* @see #getLink
*/
protected void setLink(final Long _link)
{
this.link = _link;
}
/**
* This is the getter method for instance variable {@link #link}.
*
* @return value of instance variable {@link #link}
* @throws CacheReloadException on erorr
*/
public Type getLink()
throws CacheReloadException
{
return Type.get(this.link);
}
/**
* Getter method for the instance variable {@link #dependencies}.
*
* @return value of instance variable {@link #dependencies}
* @throws CacheReloadException on error
*/
public Map getDependencies()
throws CacheReloadException
{
if (this.dependencies == null) {
this.dependencies = new TreeMap();
// in case of a rate attribute the dependencies to the currencies
// must be given
if (getProperties().containsKey("CurrencyAttribute4Rate")) {
this.dependencies.put("CurrencyAttribute4Rate",
getParent().getAttribute(getProperties().get("CurrencyAttribute4Rate")));
this.dependencies.put("TargetCurrencyAttribute4Rate",
getParent().getAttribute(getProperties().get("TargetCurrencyAttribute4Rate")));
}
}
return this.dependencies;
}
/**
* This is the getter method for instance variable {@link #parent}.
*
* @return value of instance variable {@link #parent}
* @throws CacheReloadException on error
*/
public Type getParent()
throws CacheReloadException
{
return Type.get(this.parent);
}
/**
* @return the parent Type id
*/
public Long getParentId()
{
return this.parent;
}
/**
* This is the getter method for instance variable {@link #parentSet}.
*
* @return value of instance variable {@link #parentSet}
*
*/
public AttributeSet getParentSet()
{
return this.parentSet;
}
/**
* This is the setter method for instance variable {@link #parentSet}.
*
* @param _parentSet new instance of class {@link AttributeSet} to set
*/
private void setParentSet(final AttributeSet _parentSet)
{
this.parentSet = _parentSet;
}
/**
* This is the getter method for instance variable {@link #sqlColNames}.
*
* @return value of instance variable {@link #sqlColNames}
* @see #sqlColNames
*/
public ArrayList getSqlColNames()
{
return this.sqlColNames;
}
/**
* This is the getter method for instance variable {@link #attributeType}.
*
* @return value of instance variable {@link #attributeType}
* @see #attributeType
*/
public AttributeType getAttributeType()
{
return this.attributeType;
}
/**
* This is the getter method for instance variable {@link #defaultValue}.
*
* @return value of instance variable {@link #defaultValue}
* @see #defaultValue
*/
public String getDefaultValue()
{
return this.defaultValue;
}
/**
* This is the getter method for instance variable {@link #required}.
*
* @return value of instance variable {@link #required}
* @see #required
*/
public boolean isRequired()
{
return this.required;
}
/**
* Getter method for instance variable {@link #size}.
*
* @return value of instance variable {@link #size}
*/
public int getSize()
{
return this.size;
}
/**
* Getter method for instance variable {@link #scale}.
*
* @return value of instance variable {@link #scale}
*/
public int getScale()
{
return this.scale;
}
/**
* Method to get the dimension related to this attribute.
*
* @return Dimension
*/
public Dimension getDimension()
{
Dimension ret = null;
try {
ret = Dimension.get(UUID.fromString(this.dimensionUUID));
} catch (final CacheReloadException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return ret;
}
/**
* Has this attribute an UoM.
*
* @return true id dimensionUUId!=null, else false
*/
public boolean hasUoM()
{
return this.dimensionUUID != null;
}
/**
* Prepares for given _values
depending on this attribute the
* _insert
into the database.
*
* @param _insert SQL insert statement for related {@link #sqlTable}
* @param _values values to insert
* @throws SQLException if values could not be inserted
*/
public void prepareDBInsert(final SQLInsert _insert,
final Object... _values)
throws SQLException
{
Object[] tmp = _values;
try {
final List returns = executeEvents(EventType.UPDATE_VALUE, ParameterValues.CLASS, this,
ParameterValues.OTHERS, _values);
for (final Return aRet : returns) {
if (aRet.contains(ReturnValues.VALUES)) {
tmp = (Object[]) aRet.get(ReturnValues.VALUES);
}
}
} catch (final EFapsException e) {
throw new SQLException(e);
}
this.attributeType.getDbAttrType().prepareInsert(_insert, this, tmp);
}
/**
* Prepares for given _values
depending on this attribute the
* _update
into the database.
*
* @param _update SQL update statement for related {@link #sqlTable}
* @param _values values to update
* @throws SQLException if values could not be inserted
*/
public void prepareDBUpdate(final SQLUpdate _update,
final Object... _values)
throws SQLException
{
Object[] tmp = _values;
try {
final List returns = executeEvents(EventType.UPDATE_VALUE, ParameterValues.CLASS, this,
ParameterValues.OTHERS, _values);
for (final Return aRet : returns) {
if (aRet.contains(ReturnValues.VALUES)) {
tmp = (Object[]) aRet.get(ReturnValues.VALUES);
}
}
} catch (final EFapsException e) {
throw new SQLException(e);
}
this.attributeType.getDbAttrType().prepareUpdate(_update, this, tmp);
}
/**
*
* @param _objectList object list from the database
* @return found value
* @throws EFapsException if values could not be read from the
* _objectList
*/
public Object readDBValue(final List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy