net.smartlab.web.BusinessObjectFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of smartweb Show documentation
Show all versions of smartweb Show documentation
SmartWeb is a web application development meta framework based on Jakarta Struts, Hibernate and other open source frameworks and libraries.
/*
* The SmartWeb Framework
* Copyright (C) 2004-2006
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* For further informations on the SmartWeb Framework please visit
*
* http://smartweb.sourceforge.net
*/
package net.smartlab.web;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.smartlab.web.DataAccessObject.SearchInfo.Filter;
import net.smartlab.web.bean.ConversionException;
import net.smartlab.web.bean.ConverterManager;
import net.smartlab.web.config.FactoryConfigurationStrategy;
import net.smartlab.web.config.JNDIConfigurationStrategy;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.criterion.Expression;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.impl.CriteriaImpl;
import org.hibernate.impl.SessionImpl;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.transform.ResultTransformer;
/**
* This class provides basic template for an Hibernate based implementation of
* the DAO pattern.
*
* @author rlogiacco,gperrone
* @uml.dependency supplier="net.smartlab.web.DataTransferObject"
* @uml.dependency
* supplier="net.smartlab.web.config.FactoryConfigurationStrategy"
*/
public abstract class BusinessObjectFactory implements DataAccessObject {
/**
* Provides logging capabilities to the factory.
*/
protected final Log logger = LogFactory.getLog(this.getClass());
/**
* Stores the Hibernate Session instance available for this request.
*/
private static final ThreadLocal sessions = new ThreadLocal();
/**
* Stores the Hibernate Transaction instance available for this request.
*/
private static final ThreadLocal transaction = new ThreadLocal();
/**
* Caches a reference to the Hibernate Session Factory to avoid further
* lookups.
*/
protected SessionFactory factory;
/**
* Strategy to retrieve the configuration file.
*/
private static FactoryConfigurationStrategy strategy = new JNDIConfigurationStrategy();
static {
try {
String strategy = System.getProperty("smartweb.factory.strategy");
if (strategy != null) {
BusinessObjectFactory.strategy = (FactoryConfigurationStrategy)Class.forName(strategy).newInstance();
} else {
LogFactory.getLog(BusinessObjectFactory.class).warn(
"No configuration found: falling back to default configuration");
}
} catch (Exception e) {
LogFactory.getLog(BusinessObjectFactory.class).fatal("Error configuring SmartWeb", e);
}
}
/**
* Changes the strategy used to configure the framework.
*
* @param strategy an implementation of the
* FactoryConfigurationStrategy
interface.
*/
public static void setConfigurationStrategy(FactoryConfigurationStrategy strategy) {
BusinessObjectFactory.strategy = strategy;
}
/**
* Closes the connection to the persistence tier.
*
* @throws DAOException if the persistence tier generates any error while
* performing the resource release.
*/
public static void close() throws DAOException {
Map sessions = (Map)BusinessObjectFactory.sessions.get();
if (sessions != null) {
Iterator iterator = sessions.keySet().iterator();
while (iterator.hasNext()) {
Session session = (Session)sessions.get(iterator.next());
if (session != null) {
try {
session.flush();
session.close();
} catch (HibernateException he) {
throw new DAOException("session.error.close", he);
} finally {
BusinessObjectFactory.sessions.set(null);
}
}
}
}
}
/**
* @TODO documentation
* @throws DAOException
*/
public static void flush() throws DAOException {
Map sessions = (Map)BusinessObjectFactory.sessions.get();
if (sessions != null) {
Iterator iterator = sessions.keySet().iterator();
while (iterator.hasNext()) {
Session session = (Session)sessions.get(iterator.next());
if (session != null) {
try {
session.flush();
} catch (HibernateException he) {
throw new DAOException("session.error.close", he);
} finally {
BusinessObjectFactory.sessions.set(null);
}
}
}
}
}
/**
* Protected default constructor to allow subclassing. Provides the startup
* initialization and the Hibernate Session Factory lookup. The Hibernate
* configuration file used must reside into the META-INF
* directory of the topmost packaging archive and should be named
* smartweb.jar.hcf
or have the name of the JAR file containing
* the subclass followed by the .hcf
suffix. TODO example
*/
protected BusinessObjectFactory() {
this.factory = strategy.getSessionFactory(this);
}
/**
* Returns the current Hibernate Session. If a Session was previously
* established during the same request the already established instance is
* returned otherwise a new instance is retriven from the Session Factory.
*
* @return the current connection to the persistence layer or a new one if
* not previously established.
* @throws DAOException if an error occurs trying to establish the
* connection.
*/
protected Session current() throws DAOException {
if (logger.isDebugEnabled()) {
logger.debug("current() - start");
}
Map sessions = (Map)BusinessObjectFactory.sessions.get();
if (sessions == null) {
sessions = new HashMap();
}
try {
Session session = (Session)sessions.get(factory);
if (session == null) {
try {
session = factory.openSession();
sessions.put(factory, session);
BusinessObjectFactory.sessions.set(sessions);
} catch (Exception e) {
throw new DAOException("session.error.config", e);
}
}
return session;
} catch (Exception e) {
throw new DAOException("session.error.config.not-found", e);
}
}
/**
* @see net.smartlab.web.DataAccessObject#findByKey(java.io.Serializable)
*/
public Object findByKey(Serializable key) throws DAOException {
if (logger.isDebugEnabled()) {
logger.debug("findByKey(key = " + key + ") - start");
}
Serializable convertedKey = this.convertKey(key);
if (convertedKey == null) {
try {
logger.debug("findByKey(key = " + key + ") - new instance");
return this.getMappedClass().newInstance();
} catch (Exception e) {
logger.debug("findByKey(key = " + key + ") - instantiation failed", e);
throw new DAOException("session.error.select", e);
}
} else {
Session session = this.current();
try {
return session.get(this.getMappedClass(), convertedKey);
} catch (HibernateException he) {
logger.debug("findByKey(key = " + key + ") - deserialization failed", he);
throw new UndefinedKeyException(key, this.getMappedClass(), he);
}
}
}
/**
* @TODO documentation
* @param key
* @param detached
* @return
* @throws DAOException
*/
public Object findByKey(Serializable key, String[] detached) throws DAOException {
if (logger.isDebugEnabled()) {
logger.debug("findByKey(key = " + key + ", detached = " + detached + ") - start");
}
Serializable convertedKey = this.convertKey(key);
if (convertedKey == null) {
try {
return this.getMappedClass().newInstance();
} catch (Exception e) {
logger.debug("findByKey(key = " + key + ") - instantiation failed", e);
throw new DAOException("session.error.select", e);
}
} else {
Session session = this.current();
try {
EntityPersister persister = ((SessionImpl)session).getFactory().getEntityPersister(
this.getMappedClass().getName());
Criteria criteria = session.createCriteria(this.getMappedClass());
criteria.add(Expression.eq(persister.getIdentifierPropertyName(), key));
for (int i = 0; i < detached.length; i++) {
criteria.setFetchMode(detached[i], FetchMode.JOIN);
}
return criteria.uniqueResult();
} catch (HibernateException he) {
logger.debug("findByKey(key = " + key + ", detached = " + detached + ") - deserialization failed", he);
throw new UndefinedKeyException(key, this.getMappedClass(), he);
}
}
}
/**
* @see net.smartlab.web.DataAccessObject#remove(java.lang.Object)
*/
public void remove(Object object) throws DAOException {
if (logger.isDebugEnabled()) {
logger.debug("remove(object = " + object + ") - start");
}
try {
this.current().delete(object);
} catch (HibernateException he) {
logger.debug("remove(object = " + object + ") - failed", he);
throw new DAOException("session.error.remove", he);
}
}
/**
* @see net.smartlab.web.DataAccessObject#update(java.lang.Object)
*/
public void update(Object object) throws DAOException {
if (logger.isDebugEnabled()) {
logger.debug("update(object = " + object + ") - start");
}
try {
this.current().saveOrUpdate(object);
} catch (HibernateException he) {
logger.debug("update(object = " + object + ") - failed", he);
this.current().clear();
throw new DAOException("session.error.update", he);
}
}
/**
* @see net.smartlab.web.DataAccessObject#list(net.smartlab.web.DataAccessObject.SearchInfo)
*/
public Collection list(SearchInfo info) throws DAOException {
if (logger.isDebugEnabled()) {
logger.debug("list(info = " + info + ") - start");
}
Criteria criteria = this.createCriteria(info);
try {
return criteria.list();
} catch (HibernateException he) {
logger.debug("list(info = " + info + ") - failed", he);
throw new DAOException("session.error.search", he);
}
}
/**
* Returns a collection of objects representing all the persistence tier
* informations matching the specified set of unique identification keys and
* search criterias. WARNING: the field used to search for
* matching keys must be named id
.
*
* @param keys the set of keys to be matched.
* @param info the additional criterias to be used to search the persistence
* tier.
* @return a collection of matching entities.
* @throws DAOException if an error occur while accessing the persistence
* tier
*/
public Collection listByKeySet(Set keys, SearchInfo info) throws DAOException {
return this.listByKeySet("id", keys, info);
}
/**
* Returns a collection of objects representing all the persistence tier
* informations matching the specified set of unique identification keys and
* search criterias.
*
* @param keyFieldName the fieldName to be matched for unique identificatio
* key.
* @param keys the set of keys to be matched.
* @param info the additional criterias to be used to search the persistence
* tier.
* @return a collection of matching entities.
* @throws DAOException if an error occur while accessing the persistence
* tier
*/
public Collection listByKeySet(String keyFieldName, Set keys, SearchInfo info) throws DAOException {
if (logger.isDebugEnabled()) {
logger.debug("list(keyFieldName = " + keyFieldName + ", keys = " + keys + ", info = " + info + ") - start");
}
Criteria criteria = this.createCriteria(info);
keys = this.convertKeys(keys);
criteria.add(Expression.in(keyFieldName, keys));
try {
return criteria.list();
} catch (HibernateException he) {
throw new DAOException("session.error.search", he);
}
}
/**
* Returns a paginable collection of objects representing all the
* persistence tier informations matching the specified search criterias.
*
* @param info the criterias to be used filter the instances.
* @return a paginable collection of objects matching the specified search
* criterias.
* @throws DAOException if an error occur while accessing the persistence
* tier
*/
public Collection page(SearchInfo info) throws DAOException {
if (logger.isDebugEnabled()) {
logger.debug("page(info = " + info + ") - start");
}
Criteria criteria = this.createCriteria(info);
try {
return new Paginator(criteria);
} catch (HibernateException he) {
logger.debug("page(info = " + info + ") - error", he);
throw new DAOException("session.error.paging", he);
}
}
/**
* TODO documentation
*
* @return
*/
public abstract Class getMappedClass();
/**
* Converts a generic serializable object to the type used as unique key
* identifier for this type of BusinessObject. The default implementation
* converts String or Number to Long using the o
value to
* identify non-persisted instances. If your business definition requires a
* different conversion you should override this method to provide your own
* conversion strategy.
*
* @param key the generic serializable key that needs to be converted.
* @return the key representation using the correct type or
* null
if the providen key doesn't represent a valid
* identifier for a persisted BusinessObject.
*/
public Serializable convertKey(Serializable key) {
if (key != null) {
if (key instanceof String) {
key = ((String)key).trim();
if (((String)key).length() == 0 || key.equals("0")) {
return null;
} else {
return new Long((String)key);
}
} else if (key instanceof Number) {
if (((Number)key).longValue() == 0) {
return null;
} else {
return new Long(((Number)key).toString());
}
}
}
return key;
}
/**
* Converts a generic set of serializable objects to a set containing
* objects of the type used as unique key identifier for this type of
* BusinessObject using the convertKey()
method.
*
* @param keys the java.util.Set
of serializable objects to be
* converted.
* @return a java.util.Set
containing appropriately converted
* keys.
*/
public Set convertKeys(Collection keys) {
Set converted = new HashSet(keys.size());
Iterator iterator = keys.iterator();
while (iterator.hasNext()) {
converted.add(this.convertKey((Serializable)iterator.next()));
}
return converted;
}
/**
* Creates an Hibernate Criteria
instance using filtering and
* ordering rules defined through the SearchInfo
structure.
*
* @param info
* @return
* @throws DAOException
*/
public Criteria createCriteria(SearchInfo info) throws DAOException {
if (logger.isDebugEnabled()) {
logger.debug("createCriteria(info = " + info + ") - start");
}
Session session = this.current();
Criteria criteria = session.createCriteria(this.getMappedClass());
if (info != null) {
ClassMetadata metadata = session.getSessionFactory().getClassMetadata(this.getMappedClass());
ConverterManager converter = ConverterManager.getDefault();
if (info.isUnion()) {
// TODO the filters are in OR
}
Iterator filters = info.getFilters().iterator();
while (filters.hasNext()) {
Filter filter = (Filter)filters.next();
if (logger.isTraceEnabled()) {
logger.trace("createCriteria(info = " + info + ") - parsing filter `" + filter + "`");
}
Class type = metadata.getPropertyType(filter.getColumn()).getReturnedClass();
try {
switch (filter.getCondition()) {
case SearchInfo.EQUALS:
for (int i = 0; i < filter.getValues().length; i++) {
Object value = converter.convert(type, filter.getValue(i),
info.getLocale());
criteria.add(Expression.eq(filter.getColumn(), value));
}
break;
case SearchInfo.GREATER:
for (int i = 0; i < filter.getValues().length; i++) {
Object value = converter.convert(type, filter.getValue(i),
info.getLocale());
criteria.add(Expression.gt(filter.getColumn(), value));
}
break;
case SearchInfo.GREATER_EQUALS:
for (int i = 0; i < filter.getValues().length; i++) {
Object value = converter.convert(type, filter.getValue(i),
info.getLocale());
criteria.add(Expression.ge(filter.getColumn(), value));
}
break;
case SearchInfo.LESSER:
for (int i = 0; i < filter.getValues().length; i++) {
Object value = converter.convert(type, filter.getValue(i),
info.getLocale());
criteria.add(Expression.lt(filter.getColumn(), value));
}
break;
case SearchInfo.LESSER_EQUALS:
for (int i = 0; i < filter.getValues().length; i++) {
Object value = converter.convert(type, filter.getValue(i),
info.getLocale());
criteria.add(Expression.le(filter.getColumn(), value));
}
break;
case SearchInfo.NOT_EQUALS:
for (int i = 0; i < filter.getValues().length; i++) {
Object value = converter.convert(type, filter.getValue(i),
info.getLocale());
criteria.add(Expression.ne(filter.getColumn(), value));
}
break;
case SearchInfo.BETWEEN:
Object start = converter.convert(type, filter.getValue(0),
info.getLocale());
Object stop = converter.convert(type, filter.getValue(1),
info.getLocale());
criteria.add(Expression.between(filter.getColumn(), start, stop));
break;
case SearchInfo.LIKE:
for (int i = 0; i < filter.getValues().length; i++) {
Object value = converter.convert(type, filter.getValue(i),
info.getLocale());
criteria.add(Expression.like(filter.getColumn(), value));
}
break;
case SearchInfo.ILIKE:
for (int i = 0; i < filter.getValues().length; i++) {
Object value = converter.convert(type, filter.getValue(i),
info.getLocale());
criteria.add(Expression.ilike(filter.getColumn(), value));
}
break;
case SearchInfo.NULL:
criteria.add(Expression.isNull(filter.getColumn()));
break;
case SearchInfo.NOT_NULL:
criteria.add(Expression.isNotNull(filter.getColumn()));
break;
}
} catch (ConversionException ce) {
logger.warn("Unable to convert filter `" + filter + "`", ce);
}
}
if (info.getOrder() != null && info.getOrder().length() > 0) {
if (info.isDescendant()) {
criteria.addOrder(Order.desc(info.getOrder()));
} else {
criteria.addOrder(Order.asc(info.getOrder()));
}
}
}
return criteria;
}
/**
* TODO documentation
*
* @throws DAOException
*/
public void begin() throws DAOException {
if (logger.isDebugEnabled()) {
logger.debug("begin() - start");
}
if (BusinessObjectFactory.transaction.get() == null) {
try {
BusinessObjectFactory.transaction.set(this.current().beginTransaction());
} catch (HibernateException he) {
logger.debug("begin() - error", he);
throw new DAOException("session.error.begin", he);
}
} else {
logger.warn("begin() - transaction already started");
}
}
/**
* TODO documentation
*
* @throws DAOException
*/
public void commit() throws DAOException {
if (logger.isDebugEnabled()) {
logger.debug("commit() - start");
}
Transaction transaction = (Transaction)BusinessObjectFactory.transaction.get();
try {
transaction.commit();
} catch (HibernateException he) {
logger.debug("commit() - error", he);
throw new DAOException("session.error.commit", he);
} catch (NullPointerException npe) {
logger.debug("commit() - transaction never started");
throw new DAOException("session.error.commit");
} finally {
BusinessObjectFactory.transaction.set(null);
}
}
/**
* TODO documentation
*
* @throws DAOException
*/
public void rollback() throws DAOException {
if (logger.isDebugEnabled()) {
logger.debug("rollback() - start");
}
Transaction transaction = (Transaction)BusinessObjectFactory.transaction.get();
try {
transaction.rollback();
} catch (HibernateException he) {
logger.debug("rollback() - error", he);
throw new DAOException("session.error.rollback", he);
} catch (NullPointerException npe) {
logger.warn("rollback() - transaction never started", npe);
} finally {
BusinessObjectFactory.transaction.set(null);
}
}
/**
* TODO documentation
*/
public class Paginator extends net.smartlab.web.page.Paginator implements Collection {
/**
* Logger for this class
*/
private final Log logger = LogFactory.getLog(Paginator.class);
/**
* References the Hibernate query or criteria passed to the constructor.
* It cannot be null.
*/
private Object statement;
/**
* Constructs an instance on an Hibernate criteria with an unlimited
* number of items per page and an unlimited number of pages displayed.
*
* @param criteria the Hibernate criteria whose results must be
* paginated.
* @throws HibernateException if something wrong occurs accessing the
* database.
*/
public Paginator(Criteria criteria) throws HibernateException {
this(criteria, Paginator.UNLIMITED_ITEMS, Paginator.UNLIMITED_PAGES);
}
/**
* Constructs an instance on an Hibernate criteria with the specified
* number of elements per page and the specified number of pages
* displayed.
*
* @param criteria the Hibernate criteria whose results must be
* paginated.
* @param size the number of elements per page.
* @param pages the number of pages to be displayed for quick
* navigation.
* @throws HibernateException if something wrong occurs accessing the
* database.
*/
public Paginator(Criteria criteria, int size, int pages) throws HibernateException {
super(size, pages);
this.statement = criteria;
ResultTransformer rt = ((CriteriaImpl)criteria).getResultTransformer();
List temp = new ArrayList();
Iterator orderings = ((CriteriaImpl)criteria).iterateOrderings();
while (orderings.hasNext()) {
Order ordering = ((CriteriaImpl.OrderEntry)orderings.next()).getOrder();
orderings.remove();
temp.add(ordering);
}
criteria.setProjection(Projections.rowCount());
this.setCount(((Integer)criteria.uniqueResult()).intValue());
criteria.setProjection(null);
if (rt == null) {
rt = Criteria.ROOT_ENTITY;
}
criteria.setResultTransformer(rt);
orderings = temp.iterator();
while (orderings.hasNext()) {
criteria.addOrder((Order)orderings.next());
}
this.setSize(size);
}
/**
* Constructs an instance on an Hibernate query with an unlimited number
* of items per page and an unlimited number of pages displayed.
*
* @param query the Hibernate query whose results must be paginated.
* @throws DAOException if something wrong occurs accessing the
* underling data layer.
* @throws HibernateException if something wrong occurs accessing the
* database.
*/
public Paginator(Query query) throws DAOException, HibernateException {
this(query, Paginator.UNLIMITED_ITEMS, Paginator.UNLIMITED_PAGES);
}
/**
* Constructs an instance on an Hibernate query with the specified
* number of elements per page and the specified number of pages
* displayed. FIXME the computation of rowCount is still slow on long
* lists.
*
* @param query the Hibernate query whose results must be paginated.
* @param size the number of elements per page.
* @param pages the number of pages to be displayed for quick
* navigation.
* @throws DAOException if something wrong occurs accessing the
* underling data layer.
* @throws HibernateException if something wrong occurs accessing the
* database.
*/
public Paginator(Query query, int size, int pages) throws DAOException, HibernateException {
super(size, pages);
this.statement = query;
int queryCount = query.count();
this.setCount(queryCount);
this.setSize(size);
}
/**
* @see net.smartlab.web.page.Paginator#setPage(int)
*/
public void setPage(int page) {
if (logger.isDebugEnabled()) {
logger.debug("setPage(page = " + page + ") - start");
}
if (statement instanceof Criteria) {
((Criteria)this.statement).setFirstResult((page - 1) * super.getPageSize());
} else {
((Query)this.statement).setFirstResult((page - 1) * super.getPageSize());
}
super.setPage(page);
}
/**
* TODO documentation
*
* @param size
*/
public void setSize(int size) {
if (logger.isDebugEnabled()) {
logger.debug("setSize(size = " + size + ") - start");
}
if (size != UNLIMITED_ITEMS) {
super.setPageSize(size);
if (statement instanceof Criteria) {
((Criteria)this.statement).setMaxResults(size);
} else {
((Query)this.statement).setMaxResults(size);
}
} else {
super.setPageSize(this.getCount());
}
}
/**
* @see net.smartlab.web.page.Paginator#setArray()
*/
protected void setArray() {
if (logger.isDebugEnabled()) {
logger.debug("setArray() - start");
}
try {
Iterator elements = null;
if (statement instanceof Criteria) {
elements = ((Criteria)this.statement).list().iterator();
} else {
elements = ((Query)this.statement).list().iterator();
}
for (int i = 0; i < array.length && elements.hasNext(); i++) {
array[i] = elements.next();
}
} catch (HibernateException he) {
logger.error("setArray() - error", he);
}
}
/**
* @see java.util.Collection#add(java.lang.Object)
*/
public boolean add(Object obj) {
throw new UnsupportedOperationException();
}
/**
* @see java.util.Collection#addAll(java.util.Collection)
*/
public boolean addAll(Collection collection) {
throw new UnsupportedOperationException();
}
/**
* @see java.util.Collection#clear()
*/
public void clear() {
throw new UnsupportedOperationException();
}
/**
* @see java.util.Collection#contains(java.lang.Object)
*/
public boolean contains(Object item) {
if (logger.isDebugEnabled()) {
logger.debug("contains(item = " + item + ") - start");
}
for (int i = 0; i < array.length; i++) {
if (array[i].equals(item)) {
return true;
}
}
return false;
}
/**
* @see java.util.Collection#containsAll(java.util.Collection)
*/
public boolean containsAll(Collection item) {
throw new UnsupportedOperationException();
}
/**
* @see java.util.Collection#isEmpty()
*/
public boolean isEmpty() {
return super.getCount() == 0;
}
/**
* @see java.util.Collection#iterator()
*/
public Iterator iterator() {
return this;
}
/**
* @see java.util.Collection#remove(java.lang.Object)
*/
public boolean remove(Object obj) {
throw new UnsupportedOperationException();
}
/**
* @see java.util.Collection#removeAll(java.util.Collection)
*/
public boolean removeAll(Collection collection) {
throw new UnsupportedOperationException();
}
/**
* @see java.util.Collection#retainAll(java.util.Collection)
*/
public boolean retainAll(Collection collection) {
throw new UnsupportedOperationException();
}
/**
* @see java.util.Collection#size()
*/
public int size() {
return super.getCount();
}
/**
* @see java.util.Collection#toArray()
*/
public Object[] toArray() {
return array;
}
/**
* @see java.util.Collection#toArray(java.lang.Object[])
*/
public Object[] toArray(Object[] array) {
return this.array;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy