org.efaps.db.Context 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.
/*
* Copyright 2003 - 2011 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: 6555 $
* Last Changed: $Date: 2011-05-14 13:21:29 -0500 (Sat, 14 May 2011) $
* Last Changed By: $Author: [email protected] $
*/
package org.efaps.db;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.Status;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import org.efaps.admin.user.Company;
import org.efaps.admin.user.Person;
import org.efaps.admin.user.UserAttributesSet;
import org.efaps.admin.user.UserAttributesSet.UserAttributesDefinition;
import org.efaps.db.databases.AbstractDatabase;
import org.efaps.db.databases.DataBaseFactory;
import org.efaps.db.store.Resource;
import org.efaps.db.store.Store;
import org.efaps.db.transaction.ConnectionResource;
import org.efaps.init.INamingBinds;
import org.efaps.init.StartupException;
import org.efaps.util.EFapsException;
import org.joda.time.Chronology;
import org.joda.time.DateTimeZone;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author The eFaps Team
* @version $Id: Context.java 6555 2011-05-14 18:21:29Z [email protected] $
*/
public final class Context
implements INamingBinds
{
/**
* Key used to access the current company from the userattributes.
*/
public static final String CURRENTCOMPANY = "CurrentCompany";
/**
* Logging instance used in this class.
*/
private static final Logger LOG = LoggerFactory.getLogger(Context.class);
/**
* Static variable storing the database type.
*/
private static AbstractDatabase> DBTYPE;
/**
* SQL data source to the database.
*/
private static DataSource DATASOURCE;
/**
* Stores the transaction manager.
*
* @see #setTransactionManager
*/
private static TransactionManager TRANSMANAG;
/**
* STore the timeout for the transaction manager.
*/
private static int TRANSMANAGTIMEOUT = 0;
static {
try {
final InitialContext initCtx = new InitialContext();
final javax.naming.Context envCtx = (javax.naming.Context) initCtx.lookup("java:/comp/env");
Context.DATASOURCE = (DataSource) envCtx.lookup(INamingBinds.RESOURCE_DATASOURCE);
Context.DBTYPE = DataBaseFactory.getDatabase(Context.DATASOURCE.getConnection());
Context.TRANSMANAG = (TransactionManager) envCtx.lookup(INamingBinds.RESOURCE_TRANSMANAG);
try {
Context.TRANSMANAGTIMEOUT = (Integer) envCtx.lookup(INamingBinds.RESOURCE_TRANSMANAGTIMEOUT);
} catch (final NamingException e) {
// this is actual no error, so nothing is presented
Context.TRANSMANAGTIMEOUT = 0;
}
} catch (final NamingException e) {
Context.LOG.error("NamingException", e);
throw new Error(e);
} catch (final SQLException e) {
Context.LOG.error("SQLException", e);
throw new Error(e);
}
}
/**
* Each thread has his own context object. The value is automatically
* assigned from the filter class. This allows to have a different Context
* for every Users which is connect to the WebApp Server. For the case that
* a thread creates a child threat the context is inherited to this new
* thread. This is needed e.g. in JasperReport for SubReports.
* @see #inherit
*/
private static ThreadLocal INHERITTHREADCONTEXT = new InheritableThreadLocal();
/**
* Each thread has his own context object. The value is automatically
* assigned from the filter class. This allows to have a different Context
* for every Users which is connect to the WebApp Server. For the case that
* a thread creates a child threat a different context is created this is
* needed e.g. for background process form quartz.
*/
private static ThreadLocal THREADCONTEXT = new ThreadLocal();
/**
* The instance variable stores all open instances of {@link Resource}.
*
* @see #getStoreResource(Instance)
* @see #getStoreResource(Type,long)
*/
private final Set storeStore = new HashSet();
/**
* Stores all created connection resources.
*/
private final Set connectionStore = new HashSet();
/**
* Stack used to store returned connections for reuse.
*/
private final Stack connectionStack = new Stack();
/**
* Transaction for the context.
*/
private final Transaction transaction;
/**
* This is the instance variable for the SQL Connection to the database.
*
* @see #getConnection
* @see #setConnection
*/
private Connection connection = null;
/**
* This instance variable represents the user of the context.
*
* @see #getPerson
*/
private Person person = null;
/**
* The current active company.
*/
private Company company = null;
/**
* The parameters used to open a new thread context are stored in this
* instance variable (e.g. the request parameters from a http servlet are
* stored in this variable).
*
* @see #getParameters
*/
private final Map parameters;
/**
* The file parameters used to open a new thread context are stored in this
* instance variable (e.g. the request parameters from a http servlet or in
* the shell the parameters from the command shell). The file item
* represents one file which includes an input stream, the name and the
* length of the file.
*
* @see #getFileParameters
*/
private final Map fileParameters;
/**
* A map to be able to set attributes with a lifetime of a request (e.g.
* servlet request).
*
* @see #containsRequestAttribute
* @see #getRequestAttribute
* @see #setRequestAttribute
*/
private final Map requestAttributes = new HashMap();
/**
* A map to be able to set attributes with a lifetime of a session (e.g. as
* long as the user is logged in).
*
* @see #containsSessionAttribute
* @see #getSessionAttribute
* @see #setSessionAttribute
*/
private Map sessionAttributes = new HashMap();
/**
* Holds the timezone belonging to the user of this context.
*/
private DateTimeZone timezone;
/**
* Holds the locale belonging to the user of this context.
*/
private Locale locale;
/**
* Holds the chronology belonging to the user of this context.
*/
private Chronology chronology;
/**
* Holds the iso code of the language belonging to the user of this context.
*/
private String language;
/**
* If used in a webapp the context path of the webapp can be stored here, so
* that it is accessible for e.g. esjps.
*/
private String path;
/**
* Must the ThreadContext be inherit or not.
*/
private final boolean inherit;
/**
* Private Constructor.
*
* @see #begin(String, Locale, Map, Map, Map)
*
* @param _transaction Transaction to be used in this context
* @param _locale Locale to be used in this context
* @param _sessionAttributes attributes belonging to this session
* @param _parameters parameters beloonging to this session
* @param _fileParameters paramters for file up/download
* @param _inherit must the context be inherited to child threads
* @throws EFapsException on error
*/
private Context(final Transaction _transaction,
final Locale _locale,
final Map _sessionAttributes,
final Map _parameters,
final Map _fileParameters,
final boolean _inherit)
throws EFapsException
{
this.inherit = _inherit;
this.transaction = _transaction;
this.parameters = (_parameters == null) ? new HashMap() : _parameters;
this.fileParameters = (_fileParameters == null) ? new HashMap() : _fileParameters;
this.sessionAttributes = (_sessionAttributes == null) ? new HashMap() : _sessionAttributes;
try {
setConnection(Context.DATASOURCE.getConnection());
} catch (final SQLException e) {
Context.LOG.error("could not get a sql connection", e);
}
}
/**
* @return ThreadLocal related to this context
*/
private ThreadLocal getThreadLocal()
{
ThreadLocal ret;
if (this.inherit) {
ret = Context.INHERITTHREADCONTEXT;
} else {
ret = Context.THREADCONTEXT;
}
return ret;
}
/**
* Destructor of class Context
.
*/
@Override
public void finalize()
{
if (Context.LOG.isDebugEnabled()) {
Context.LOG.debug("finalize context for " + this.person);
Context.LOG.debug("connection is " + getConnection());
}
if (this.connection != null) {
try {
this.connection.close();
} catch (final SQLException e) {
Context.LOG.error("could not close a sql connection", e);
}
}
}
/**
* The method tests if all resources (JDBC connection and store resources)
* are closed, that means that the resources are freeed and returned for
* reuse.
*
* @return true if all resources are closed, otherwise false
* is returned
* @see #connectionStore
* @see #storeStore
*/
public boolean allConnectionClosed()
{
boolean closed = true;
for (final ConnectionResource con : this.connectionStore) {
if (con.isOpened()) {
closed = false;
break;
}
}
if (closed) {
for (final Resource store : this.storeStore) {
if (store.isOpened()) {
closed = false;
break;
}
}
}
return closed;
}
/**
* Close this contexts, meaning this context object is removed as thread
* context.
* If not all connection are closed, all connection are closed.
*
* TODO: better description
*/
public void close()
{
if (Context.LOG.isDebugEnabled()) {
Context.LOG.debug("close context for " + this.person);
Context.LOG.debug("connection is " + getConnection());
}
if (this.connection != null) {
try {
this.connection.close();
} catch (final SQLException e) {
Context.LOG.error("could not close a sql connection", e);
}
}
setConnection(null);
if ((getThreadLocal().get() != null) && (getThreadLocal().get() == this)) {
getThreadLocal().set(null);
}
// check if all JDBC connection are close...
for (final ConnectionResource con : this.connectionStore) {
try {
if ((con.getConnection() != null) && !con.getConnection().isClosed()) {
con.getConnection().close();
Context.LOG.error("connection was not closed!");
}
} catch (final SQLException e) {
Context.LOG.error("QLException is thrown while trying to get close status of "
+ "connection or while trying to close", e);
}
}
}
/**
* Method to abort the transaction.
*
* @throws EFapsException if setting of rollback was not successfully
*/
public void abort()
throws EFapsException
{
try {
this.transaction.setRollbackOnly();
} catch (final SystemException e) {
throw new EFapsException(getClass(), "abort.SystemException", e);
}
}
/**
* Returns a opened connection resource. If a previous close connection
* resource already exists, this already existing connection resource is
* returned.
*
* @return opened connection resource
* @throws EFapsException if connection resource cannot be created
*/
public ConnectionResource getConnectionResource()
throws EFapsException
{
ConnectionResource con = null;
if (this.connectionStack.isEmpty()) {
try {
con = new ConnectionResource(Context.DATASOURCE.getConnection());
} catch (final SQLException e) {
throw new EFapsException(getClass(), "getConnectionResource.SQLException", e);
}
this.connectionStore.add(con);
} else {
con = this.connectionStack.pop();
}
con.open();
return con;
}
/**
* @param _con ConnectionResource
*/
public void returnConnectionResource(final ConnectionResource _con)
{
// System.out.println("returnConnectionResource.con="+_con);
// TODO throw error
// if (_con == null) {
// throw new EFapsException();
// }
this.connectionStack.push(_con);
}
/**
* Method to get the sore resource.
*
* @param _instance Instance to get the StoreResource for
* @throws EFapsException on error
* @return StoreResource
* @see #getStoreResource(Type,long)
*/
public Resource getStoreResource(final Instance _instance)
throws EFapsException
{
Resource storeRsrc = null;
final Store store = Store.get(_instance.getType().getStoreId());
storeRsrc = store.getResource(_instance);
storeRsrc.open();
this.storeStore.add(storeRsrc);
return storeRsrc;
}
/**
* If a person is assigned to this context, the id of this person is
* returned. Otherwise the default person id value is returned. The method
* guarantees to return value which is valid!
* The value could be used e.g. if a a value is inserted into the database
* and the person id is needed for the creator and / or modifier.
*
* @return person id of current person or default person id value
*/
public long getPersonId()
{
long ret = 1;
if (this.person != null) {
ret = this.person.getId();
}
return ret;
}
/**
* Method to get a parameter from the context.
*
* @param _key Key for the parameter
* @return String value of the parameter
*/
public String getParameter(final String _key)
{
String value = null;
if (this.parameters != null) {
final String[] values = this.parameters.get(_key);
if ((values != null) && (values.length > 0)) {
value = values[0];
}
}
return value;
}
/**
* Getter method for instance variable {@link #path}.
*
* @return value of instance variable {@link #path}
*/
public String getPath()
{
return this.path;
}
/**
* Setter method for instance variable {@link #path}.
*
* @param _path value for instance variable {@link #path}
*/
public void setPath(final String _path)
{
this.path = _path;
}
/**
* Returns true if request attributes maps one or more keys to the specified
* object. More formally, returns true if and only if the request
* attributes contains at least one mapping to a object o such that (o==null
* ? o==null : o.equals(o)).
*
* @param _key key whose presence in the request attributes is to be tested
* @return true if the request attributes contains a mapping for
* given key, otherwise false
* @see #requestAttributes
* @see #getRequestAttribute
* @see #setRequestAttribute
*/
public boolean containsRequestAttribute(final String _key)
{
return this.requestAttributes.containsKey(_key);
}
/**
* Returns the object to which this request attributes maps the specified
* key. Returns null
if the request attributes contains no
* mapping for this key. A return value of null
does not
* necessarily indicate that the request attributes contains no mapping for
* the key; it's also possible that the request attributes explicitly maps
* the key to null. The {@link #containsRequestAttribute} operation may be
* used to distinguish these two cases.
* More formally, if the request attributes contains a mapping from a key k
* to a object o such that (key==null ? k==null : key.equals(k)), then this
* method returns o; otherwise it returns null
(there can be at
* most one such mapping).
*
* @param _key key name of the mapped attribute to be returned
* @return object to which the request attribute contains a mapping for
* specified key, or null
if not specified in the
* request attributes
* @see #requestAttributes
* @see #containsRequestAttribute
* @see #setRequestAttribute
*/
public Object getRequestAttribute(final String _key)
{
return this.requestAttributes.get(_key);
}
/**
* Associates the specified value with the specified key in the request
* attributes. If the request attributes previously contained a mapping for
* this key, the old value is replaced by the specified value.
*
* @param _key key name of the attribute to set
* @param _value _value of the attribute to set
* @return Object
* @see #requestAttributes
* @see #containsRequestAttribute
* @see #getRequestAttribute
*/
public Object setRequestAttribute(final String _key,
final Object _value)
{
return this.requestAttributes.put(_key, _value);
}
/**
* Returns true if session attributes maps one or more keys to the specified
* object. More formally, returns true if and only if the session
* attributes contains at least one mapping to a object o such that (o==null
* ? o==null : o.equals(o)).
*
* @param _key key whose presence in the session attributes is to be tested
* @return true if the session attributes contains a mapping for
* given key, otherwise false
* @see #sessionAttributes
* @see #getSessionAttribute
* @see #setSessionAttribute
*/
public boolean containsSessionAttribute(final String _key)
{
return this.sessionAttributes.containsKey(_key);
}
/**
* Returns the object to which this session attributes maps the specified
* key. Returns null
if the session attributes contains no
* mapping for this key. A return value of null
does not
* necessarily indicate that the session attributes contains no mapping for
* the key; it's also possible that the session attributes explicitly maps
* the key to null. The {@link #containsSessionAttribute} operation may be
* used to distinguish these two cases.
* More formally, if the session attributes contains a mapping from a key k
* to a object o such that (key==null ? k==null : key.equals(k)), then this
* method returns o; otherwise it returns null
(there can be at
* most one such mapping).
*
* @param _key key name of the mapped attribute to be returned
* @return object to which the session attribute contains a mapping for
* specified key, or null
if not specified in the
* session attributes
* @see #sessionAttributes
* @see #containsSessionAttribute
* @see #setSessionAttribute
*/
public Object getSessionAttribute(final String _key)
{
return this.sessionAttributes.get(_key);
}
/**
* Associates the specified value with the specified key in the session
* attributes. If the session attributes previously contained a mapping for
* this key, the old value is replaced by the specified value.
*
* @param _key key name of the attribute to set
* @param _value value of the attribute to set
* @return Object
* @see #sessionAttributes
* @see #containsSessionAttribute
* @see #getSessionAttribute
*/
public Object setSessionAttribute(final String _key,
final Object _value)
{
return this.sessionAttributes.put(_key, _value);
}
/**
* This method retrieves a UserAttribute of the Person this Context belongs
* to. The UserAttributes are stored in the {@link #sessionAttributes} Map,
* therefore are thought to be valid for one session.
*
* @param _key key to Search for
* @return String with the value
* @throws EFapsException on error
*/
public String getUserAttribute(final String _key)
throws EFapsException
{
if (containsSessionAttribute(UserAttributesSet.CONTEXTMAPKEY)) {
return ((UserAttributesSet) getSessionAttribute(UserAttributesSet.CONTEXTMAPKEY)).getString(_key);
} else {
throw new EFapsException(Context.class, "getUserAttribute.NoSessionAttribute");
}
}
/**
* This method determines if UserAttribute of the Person this Context
* belongs to exists.The UserAttributes are stored in the
* {@link #sessionAttributes} Map, therefore are thought to be valid for one
* session.
*
* @param _key key to Search for
* @return true if found, else false
*
* @throws EFapsException on error
*/
public boolean containsUserAttribute(final String _key)
throws EFapsException
{
boolean ret = false;
if (containsSessionAttribute(UserAttributesSet.CONTEXTMAPKEY)) {
ret = ((UserAttributesSet) getSessionAttribute(UserAttributesSet.CONTEXTMAPKEY)).containsKey(_key);
}
return ret;
}
/**
* Set a new UserAttribute for the UserAttribute of the Person this
* Context.The UserAttributes are stored in the {@link #sessionAttributes}
* Map, therefore are thought to be valid for one session.
*
* @param _key Key of the UserAttribute
* @param _value Value of the UserAttribute
* @throws EFapsException on error
*/
public void setUserAttribute(final String _key,
final String _value)
throws EFapsException
{
if (containsSessionAttribute(UserAttributesSet.CONTEXTMAPKEY)) {
((UserAttributesSet) getSessionAttribute(UserAttributesSet.CONTEXTMAPKEY)).set(_key, _value);
} else {
final UserAttributesSet userAttribute = new UserAttributesSet(getPersonId());
userAttribute.set(_key, _value);
setSessionAttribute(UserAttributesSet.CONTEXTMAPKEY, userAttribute);
}
}
/**
* Set a new UserAttribute for the UserAttribute of the Person this
* Context.The UserAttributes are stored in the {@link #sessionAttributes}
* Map, therefore are thought to be valid for one session.
*
* @param _key Key of the UserAttribute
* @param _value Value of the UserAttribute
* @param _definition Definition
* @throws EFapsException on error
*/
public void setUserAttribute(final String _key,
final String _value,
final UserAttributesDefinition _definition)
throws EFapsException
{
if (containsSessionAttribute(UserAttributesSet.CONTEXTMAPKEY)) {
((UserAttributesSet) getSessionAttribute(UserAttributesSet.CONTEXTMAPKEY)).set(_key, _value, _definition);
} else {
throw new EFapsException(Context.class, "getUserAttributes.NoSessionAttribute");
}
}
/**
* Method to get the UserAttributesSet of the user of this context.
*
* @return UserAttributesSet
* @throws EFapsException on error
*/
public UserAttributesSet getUserAttributes()
throws EFapsException
{
if (containsSessionAttribute(UserAttributesSet.CONTEXTMAPKEY)) {
return (UserAttributesSet) getSessionAttribute(UserAttributesSet.CONTEXTMAPKEY);
} else {
throw new EFapsException(Context.class, "getUserAttributes.NoSessionAttribute");
}
}
/**
* This is the getter method for instance variable {@link #connection}.
*
* @return value of instance variable {@link #connection}
* @see #connection
* @see #setConnection
*/
public Connection getConnection()
{
return this.connection;
}
/**
* This is the setter method for instance variable {@link #connection}.
*
* @param _connection new value for instance variable {@link #connection}
* @see #connection
* @see #getConnection
*/
private void setConnection(final Connection _connection)
{
this.connection = _connection;
}
/**
* This is the getter method for instance variable {@link #transaction}.
*
* @return value of instance variable {@link #transaction}
* @see #transaction
*/
public Transaction getTransaction()
{
return this.transaction;
}
/**
* This is the getter method for instance variable {@link #person}.
*
* @return value of instance variable {@link #person}
* @see #person
*/
public Person getPerson()
{
return this.person;
}
/**
* Getter method for instance variable {@link #company}.
*
* @return value of instance variable {@link #company}
*/
public Company getCompany()
{
return this.company;
}
/**
* This is the getter method for instance variable {@link #locale}.
*
* @return value of instance variable {@link #locale}
* @see #locale
*/
public Locale getLocale()
{
return this.locale;
}
/**
* This is the getter method for instance variable {@link #timezone}.
*
* @return value of instance variable {@link #timezone}
* @see #timezone
*/
public DateTimeZone getTimezone()
{
return this.timezone;
}
/**
* This is the getter method for instance variable {@link #chronology}.
*
* @return value of instance variable {@link #chronology}
* @see #locale
*/
public Chronology getChronology()
{
return this.chronology;
}
/**
* Getter method for instance variable {@link #language}.
*
* @return value of instance variable {@link #language}
*/
public String getLanguage()
{
return this.language;
}
/**
* This is the getter method for instance variable {@link #parameters}.
*
* @return value of instance variable {@link #parameters}
* @see #parameters
*/
public Map getParameters()
{
return this.parameters;
}
/**
* This is the getter method for instance variable {@link #fileParameters}.
*
* @return value of instance variable {@link #fileParameters}
* @see #fileParameters
*/
public Map getFileParameters()
{
return this.fileParameters;
}
/**
* Is a Thread active.
*
* @return true if either the ThreadContext or the
* Inherited ThreadContext is no null
*/
public static boolean isThreadActive()
{
return Context.INHERITTHREADCONTEXT.get() != null || Context.THREADCONTEXT.get() != null;
}
/**
* The method checks if for the current thread a context object is defined.
* This found context object is returned.
*
* @return defined context object of current thread
* @throws EFapsException if no context object for current thread is defined
* @see #INHERITTHREADCONTEXT
*/
public static Context getThreadContext()
throws EFapsException
{
Context context = Context.THREADCONTEXT.get();
if (context == null) {
context = Context.INHERITTHREADCONTEXT.get();
}
if (context == null) {
throw new EFapsException(Context.class, "getThreadContext.NoContext4ThreadDefined");
}
return context;
}
/**
* Method to get a new Context.
*
* @see #begin(String, Locale, Map, Map, Map)
* @throws EFapsException on error
* @return new Context
*/
public static Context begin()
throws EFapsException
{
return Context.begin(null, null, null, null, null, true);
}
/**
* Method to get a new Context.
*
* @see #begin(String, Locale, Map, Map, Map)
* @param _userName Naem of the user the Context must be created for
* @throws EFapsException on error
* @return new Context
*
*/
public static Context begin(final String _userName)
throws EFapsException
{
return Context.begin(_userName, null, null, null, null, true);
}
/**
* Method to get a new Context.
*
* @see #begin(String, Locale, Map, Map, Map)
* @param _userName Naem of the user the Context must be created for
* @param _inherit must the context be inherited to child threads
* @throws EFapsException on error
* @return new Context
*
*/
public static Context begin(final String _userName,
final boolean _inherit)
throws EFapsException
{
return Context.begin(_userName, null, null, null, null, _inherit);
}
/**
* For current thread a new context object must be created.
*
* @param _userName name of current user to set
* @param _locale locale instance (which language settings has the user)
* @param _sessionAttributes attributes for this session
* @param _parameters map with parameters for this thread context
* @param _fileParameters map with file parameters
* @param _inherit must the context be inherited to child threads
* @return new context of thread
* @throws EFapsException if a new transaction could not be started or if
* current thread context is already set
* @see #INHERITTHREADCONTEXT
*/
public static Context begin(final String _userName,
final Locale _locale,
final Map _sessionAttributes,
final Map _parameters,
final Map _fileParameters,
final boolean _inherit)
throws EFapsException
{
if ((_inherit && Context.INHERITTHREADCONTEXT.get() != null)
|| (!_inherit && Context.THREADCONTEXT.get() != null)) {
throw new EFapsException(Context.class, "begin.Context4ThreadAlreadSet");
}
try {
// the timeout set is reseted on creation of a new Current object in
// the transaction manager,
// so if the default must be overwritten it must be set explicitly
// again
if (Context.TRANSMANAGTIMEOUT > 0) {
Context.TRANSMANAG.setTransactionTimeout(Context.TRANSMANAGTIMEOUT);
}
Context.TRANSMANAG.begin();
} catch (final SystemException e) {
throw new EFapsException(Context.class, "begin.beginSystemException", e);
} catch (final NotSupportedException e) {
throw new EFapsException(Context.class, "begin.beginNotSupportedException", e);
}
Transaction transaction;
try {
transaction = Context.TRANSMANAG.getTransaction();
} catch (final SystemException e) {
throw new EFapsException(Context.class, "begin.getTransactionSystemException", e);
}
final Context context = new Context(transaction, (_locale == null) ? Locale.ENGLISH : _locale,
_sessionAttributes, _parameters, _fileParameters, _inherit);
if (_inherit) {
Context.INHERITTHREADCONTEXT.set(context);
} else {
Context.THREADCONTEXT.set(context);
}
if (_userName != null) {
context.person = Person.get(_userName);
context.locale = context.person.getLocale();
context.timezone = context.person.getTimeZone();
context.chronology = context.person.getChronology();
context.language = context.person.getLanguage();
if (_sessionAttributes != null) {
if (context.containsUserAttribute(Context.CURRENTCOMPANY)) {
final Company comp = Company.get(Long.parseLong(context.getUserAttribute(Context.CURRENTCOMPANY)));
if (comp != null && !context.person.getCompanies().isEmpty() && context.person.isAssigned(comp)) {
context.company = comp;
} else {
context.setUserAttribute(Context.CURRENTCOMPANY, "0");
}
}
if (context.company == null && context.person.getCompanies().size() > 0) {
for (final Long compID : context.person.getCompanies()) {
context.setUserAttribute(Context.CURRENTCOMPANY, compID.toString());
context.company = Company.get(compID);
break;
}
}
}
}
return context;
}
/**
* @throws EFapsException if commit of the transaction manager failed TODO:
* description
*/
public static void commit()
throws EFapsException
{
try {
Context.TRANSMANAG.commit();
} catch (final IllegalStateException e) {
throw new EFapsException(Context.class, "commit.IllegalStateException", e);
} catch (final SecurityException e) {
throw new EFapsException(Context.class, "commit.SecurityException", e);
} catch (final HeuristicMixedException e) {
throw new EFapsException(Context.class, "commit.HeuristicMixedException", e);
} catch (final HeuristicRollbackException e) {
throw new EFapsException(Context.class, "commit.HeuristicRollbackException", e);
} catch (final RollbackException e) {
throw new EFapsException(Context.class, "commit.RollbackException", e);
} catch (final SystemException e) {
throw new EFapsException(Context.class, "commit.SystemException", e);
} finally {
Context.getThreadContext().close();
}
}
/**
* @throws EFapsException if roll back of the transaction manager failed
*/
public static void rollback()
throws EFapsException
{
try {
Context.TRANSMANAG.rollback();
} catch (final IllegalStateException e) {
throw new EFapsException(Context.class, "rollback.IllegalStateException", e);
} catch (final SecurityException e) {
throw new EFapsException(Context.class, "rollback.SecurityException", e);
} catch (final SystemException e) {
throw new EFapsException(Context.class, "rollback.SystemException", e);
} finally {
Context.getThreadContext().close();
}
}
/**
* Is the status of transaction manager active?
*
* @return true if transaction manager is active, otherwise
* false
* @throws EFapsException if the status of the transaction manager could not
* be evaluated
* @see #TRANSMANAG
*/
public static boolean isTMActive()
throws EFapsException
{
try {
return Context.TRANSMANAG.getStatus() == Status.STATUS_ACTIVE;
} catch (final SystemException e) {
throw new EFapsException(Context.class, "isTMActive.SystemException", e);
}
}
/**
* Is a transaction associated with a target object for transaction manager?
*
* @return true if a transaction associated, otherwise false
* @throws EFapsException if the status of the transaction manager could not
* be evaluated
* @see #TRANSMANAG
*/
public static boolean isTMNoTransaction()
throws EFapsException
{
try {
return Context.TRANSMANAG.getStatus() == Status.STATUS_NO_TRANSACTION;
} catch (final SystemException e) {
throw new EFapsException(Context.class, "isTMNoTransaction.SystemException", e);
}
}
/**
* Is the status of transaction manager marked roll back?
*
* @return true if transaction manager is marked roll back, otherwise
* false
* @throws EFapsException if the status of the transaction manager could not
* be evaluated
* @see #TRANSMANAG
*/
public static boolean isTMMarkedRollback()
throws EFapsException
{
try {
return Context.TRANSMANAG.getStatus() == Status.STATUS_MARKED_ROLLBACK;
} catch (final SystemException e) {
throw new EFapsException(Context.class, "isTMMarkedRollback.SystemException", e);
}
}
/**
* Returns the database type of the default connection (database where the
* data model definition is stored).
*
* @see #DBTYPE
* @return AbstractDatabase
*/
public static AbstractDatabase> getDbType()
{
return Context.DBTYPE;
}
/**
* Resets the context to current defined values in the Javax naming
* environment.
*
* @throws StartupException if context could not be reseted to new values
* @see #DBTYPE
* @see #DATASOURCE
* @see #TRANSMANAG
* @see #TRANSMANAGTIMEOUT
*/
public static void reset()
throws StartupException
{
try {
final InitialContext initCtx = new InitialContext();
final javax.naming.Context envCtx = (javax.naming.Context) initCtx.lookup("java:comp/env");
Context.DBTYPE = (AbstractDatabase>) envCtx.lookup(INamingBinds.RESOURCE_DBTYPE);
Context.DATASOURCE = (DataSource) envCtx.lookup(INamingBinds.RESOURCE_DATASOURCE);
Context.TRANSMANAG = (TransactionManager) envCtx.lookup(INamingBinds.RESOURCE_TRANSMANAG);
try {
Context.TRANSMANAGTIMEOUT = (Integer) envCtx.lookup(INamingBinds.RESOURCE_TRANSMANAGTIMEOUT);
} catch (final NamingException e) {
// this is actual no error, so nothing is presented
Context.TRANSMANAGTIMEOUT = 0;
}
} catch (final NamingException e) {
throw new StartupException("eFaps context could not be initialized", e);
}
}
/**
* Interfaces defining file parameters used to access file parameters (e.g.
* uploads from the user within the web application).
*/
public static interface FileParameter
{
/**
* Closes the file for this this file parameter is defined (e.g. deletes
* the file in the temporary directory, if needed).
*
* @throws IOException if the close failed
*/
void close()
throws IOException;
/**
* Returns the input stream of the file for which this file parameter is
* defined.
*
* @return input stream of the file
* @throws IOException if the input stream could not be returned
*/
InputStream getInputStream()
throws IOException;
/**
* Returns the size of the file for which this file parameter is
* defined.
*
* @return size of file
*/
long getSize();
/**
* Returns the content type of the file for which this file parameter is
* defined.
*
* @return content type of the file
*/
String getContentType();
/**
* Returns the name of the file for which this file parameter is
* defined.
*
* @return name of file
*/
String getName();
/**
* Returns the name of the parameter for which this file parameter is
* defined.
*
* @return parameter name
*/
String getParameterName();
}
}