From 1455029435534c5ca53a4715b2ee2a6998ebd7c6 Mon Sep 17 00:00:00 2001 From: Ben Alex Date: Thu, 15 Sep 2005 08:13:09 +0000 Subject: [PATCH] Refactor lifecycle methods into separate files, so that subclasses can extend specific classes or interfaces to achieve the desired subset of lifecycle capabilities. --- .../domain/service/CreatableManager.java | 38 +++ .../domain/service/CreatableManagerImpl.java | 36 +++ .../domain/service/ImmutableManager.java | 226 +++++++++++++++++ .../domain/service/ImmutableManagerImpl.java | 155 ++++++++++++ .../acegisecurity/domain/service/Manager.java | 236 +----------------- .../domain/service/ManagerImpl.java | 161 +----------- .../domain/service/UpdatableManager.java | 51 ++++ .../domain/service/UpdatableManagerImpl.java | 52 ++++ 8 files changed, 562 insertions(+), 393 deletions(-) create mode 100644 domain/src/main/java/org/acegisecurity/domain/service/CreatableManager.java create mode 100644 domain/src/main/java/org/acegisecurity/domain/service/CreatableManagerImpl.java create mode 100644 domain/src/main/java/org/acegisecurity/domain/service/ImmutableManager.java create mode 100644 domain/src/main/java/org/acegisecurity/domain/service/ImmutableManagerImpl.java create mode 100644 domain/src/main/java/org/acegisecurity/domain/service/UpdatableManager.java create mode 100644 domain/src/main/java/org/acegisecurity/domain/service/UpdatableManagerImpl.java diff --git a/domain/src/main/java/org/acegisecurity/domain/service/CreatableManager.java b/domain/src/main/java/org/acegisecurity/domain/service/CreatableManager.java new file mode 100644 index 0000000000..830d5172e7 --- /dev/null +++ b/domain/src/main/java/org/acegisecurity/domain/service/CreatableManager.java @@ -0,0 +1,38 @@ +/* Copyright 2004, 2005 Acegi Technology Pty Limited + * + * 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. + */ + +package net.sf.acegisecurity.domain.service; + +import net.sf.acegisecurity.domain.PersistableEntity; + +/** + * Adds a creation method to the ImmutableManager. + * + * @author Ben Alex + * @version $Id$ + */ +public interface CreatableManager extends ImmutableManager { + //~ Methods ================================================================ + + /** + * Create a new object, with the current {@link + * PersistableEntity#getInternalId()} value being ignored. + * + * @param value (without the identity property initialized) + * + * @return the value created (with the identity property initialised) + */ + public E create(E value); +} diff --git a/domain/src/main/java/org/acegisecurity/domain/service/CreatableManagerImpl.java b/domain/src/main/java/org/acegisecurity/domain/service/CreatableManagerImpl.java new file mode 100644 index 0000000000..05a993c078 --- /dev/null +++ b/domain/src/main/java/org/acegisecurity/domain/service/CreatableManagerImpl.java @@ -0,0 +1,36 @@ +/* Copyright 2004, 2005 Acegi Technology Pty Limited + * + * 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. + */ + +package net.sf.acegisecurity.domain.service; + +import net.sf.acegisecurity.domain.PersistableEntity; + +import org.springframework.util.Assert; + +/** + * Base {@link CreatableManager} implementation. + * + * @author Ben Alex + * @version $Id$ + */ +public class CreatableManagerImpl extends ImmutableManagerImpl implements CreatableManager { + public E create(E value) { + Assert.notNull(value); + if (logger.isDebugEnabled()) { + logger.debug("Creating: " + value); + } + return dao.create(value); + } +} diff --git a/domain/src/main/java/org/acegisecurity/domain/service/ImmutableManager.java b/domain/src/main/java/org/acegisecurity/domain/service/ImmutableManager.java new file mode 100644 index 0000000000..cb52b77c2e --- /dev/null +++ b/domain/src/main/java/org/acegisecurity/domain/service/ImmutableManager.java @@ -0,0 +1,226 @@ +/* Copyright 2004, 2005 Acegi Technology Pty Limited + * + * 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. + */ + +package net.sf.acegisecurity.domain.service; + +import net.sf.acegisecurity.domain.PersistableEntity; +import net.sf.acegisecurity.domain.dao.PaginatedList; + +import java.io.Serializable; + +import java.util.Collection; +import java.util.List; + +/** + * Provides fundamental services layer capabilities for a single concrete {@link + * PersistableEntity}, using JDK 1.5 generics. + * + *

+ * This interface provides a remoting protocol compliant approach to accessing + * services layer logic for a given application. A generics-based services + * layer interface decreases development time because the basic CRUD and finder + * operations can be specified in a typesafe fashion that reuses superclass + * code. + *

+ * + *

+ * It is not envisioned that this interface will provide all services layer + * functions. The significant value of a services layer is the value-add beyond + * simply fronting the DAO or applying validation/binding logic that is better + * situated in the domain object or its validator. The type of value-adds + * expected to be provided by a services layer include incrementing business + * identifiers (eg an invoice number); generating messages for logging/audit + * purposes (thus such messages are at a business transaction level of granularity, + * instead of DAO/persistence granularity where the overall context of the + * the message becomes unclear); updating related domain objects via + * their respective services layer beans (eg an invoice services layer bean + * would call the general journal services layer bean to create the accrual + * accounting entries); making changes to a domain object that requires + * logic that is unsuitable to put into a validator because it extends + * beyond a single domain object instance or requires access to other persistent + * entities (eg computing taxation appliable to an invoice based on a break-down + * of each item on the order, its delivery destination, and the customer); + * producing messages (eg notify another system the invoice was created or + * email the customer via SMTP); provide a layer to locate transaction and + * security configuration; expose a reasonably protocol-independent interface + * to the application that can be used by a variety of web services and + * client types; ensure any returned objects are eagerly loaded to a well-defined + * interface contract etc. + *

+ * + *

+ * A single ImmutableManager implementation will typically exist for each + * {@link net.sf.acegisecurity.domain.PersistableEntity}, particularly given + * a PersistableEntity is allowed to manage multiple + * {@link net.sf.acegisecurity.domain.impl.PersistableValue}s. + * The particular PersistableEntity an implementation supports + * will be expressed by the {@link #supports(Class)} method. + *

+ * + *

No other part of the Domain subproject relies on this interface. If + * you would prefer to write your own services layer interfaces from scratch, + * this is not a problem at all. + * + * @author Ben Alex + * @version $Id$ + */ +public interface ImmutableManager { + //~ Methods ================================================================ + + /** + * Return all persistent instances, including subclasses. + * + * @return all persistence instances (an empty List will be + * returned if no matches are found) + */ + public List findAll(); + + /** + * Find a List of PersistableEntitys, searched by + * their identifiers. + * + * @param ids collection of identifiers to locate + * + * @return the values with those identifiers (an empty List + * will be returned if no matches are found) + */ + public List findId(Collection ids); + + /** + * Load a persistent instance by its identifier, although some properties + * may be lazy loaded depending on the underlying DAO implementation and/or + * persistence engine mapping document. + * + * @param id the identifier of the persistent instance desired to be + * retrieved + * + * @return the request item, or null if not found + */ + public E readId(Serializable id); + + /** + * Loads a persistent instance by its identifier, along with any + * lazy loaded properties associated with that instance. + * + * @param id the identifier of the persistent instance desired to be + * retrieved + * + * @return the request item, or null if not found + */ + public E readPopulatedId(Serializable id); + + /** + * Find persistent instances with properties matching those of the passed + * PersistableEntity. + * + *

+ * Persistent instances are matched on the basis of query by example. + * Properties whose value is null, empty + * Strings, and any Collections are ignored in + * the query by example evaluation. + *

+ * + * @param value parameters to filter on (the class of this object will + * be added to the filter) + * @param firstElement the first result (start at zero to obtain all + * results) + * @param maxElements the maximum number of results desired for this page + * of the result set + * + * @return the requested page of the result list (a properly formed + * PaginatedList is returned if no results match) + */ + public PaginatedList scroll(E value, int firstElement, + int maxElements); + + /** + * Find persistent instances with properties matching those of the passed + * PersistableEntity, with a guarantee the returned results + * will have each of the value class' immediate properties + * initialized. + * + *

+ * Persistent instances are matched on the basis of query by example. + * Properties whose value is null, empty + * Strings, and any Collections are ignored in + * the query by example evaluation. + *

+ * + * @param value parameters to filter on (the class of this object will + * be added to the filter) + * @param firstElement the first result (start at zero to obtain all + * results) + * @param maxElements the maximum number of results desired for this page + * of the result set + * + * @return the requested page of the result list (a properly formed + * PaginatedList is returned if no results match) + */ + public PaginatedList scrollPopulated(E value, int firstElement, + int maxElements); + + /** + * Find persistent instances with properties matching those of the passed + * PersistableEntity, ignoring the class of the passed + * PersistableEntity (useful if you pass a superclass, as you + * want to find all subclass instances which match). + * + * @param value parameters to filter on (the class of this object will + * NOT be added to the filter) + * @param firstElement the first result (start at zero to obtain all + * results) + * @param maxElements the maximum number of results desired for this page + * of the result set + * + * @return the requested page of the result list (a properly formed + * PaginatedList is returned if no results match) + */ + public PaginatedList scrollWithSubclasses(E value, int firstElement, + int maxElements); + + /** + * Find persistent instances with properties matching those of the passed + * PersistableEntity, ignoring the class of the passed + * PersistableEntity (useful if you pass a superclass, as you + * want to find all subclass instances which match). Guarantees the returned + * results will have each of the DAO's supports class' immediate + * properties initialized. + * + * @param value parameters to filter on (the class of this object will + * NOT be added to the filter) + * @param firstElement the first result (start at zero to obtain all + * results) + * @param maxElements the maximum number of results desired for this page + * of the result set + * + * @return the requested page of the result list (a properly formed + * PaginatedList is returned if no results match) + */ + public PaginatedList scrollPopulatedWithSubclasses(E value, int firstElement, + int maxElements); + + /** + * Indicates whether the DAO instance provides persistence services for the + * specified class. + * + * @param clazz to test, which should be an implementation of + * PersistableEntity + * + * @return true or false, indicating whether or + * not the passed class is supported by this DAO instance + */ + public boolean supports(Class clazz); + +} diff --git a/domain/src/main/java/org/acegisecurity/domain/service/ImmutableManagerImpl.java b/domain/src/main/java/org/acegisecurity/domain/service/ImmutableManagerImpl.java new file mode 100644 index 0000000000..c941336fb0 --- /dev/null +++ b/domain/src/main/java/org/acegisecurity/domain/service/ImmutableManagerImpl.java @@ -0,0 +1,155 @@ +/* Copyright 2004, 2005 Acegi Technology Pty Limited + * + * 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. + */ + +package net.sf.acegisecurity.domain.service; + +import java.io.Serializable; +import java.util.Collection; +import java.util.List; + +import net.sf.acegisecurity.domain.PersistableEntity; +import net.sf.acegisecurity.domain.dao.Dao; +import net.sf.acegisecurity.domain.dao.PaginatedList; +import net.sf.acegisecurity.domain.util.GenericsUtils; + +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.support.ApplicationObjectSupport; +import org.springframework.util.Assert; + +/** + * Base {@link ImmutableManager} implementation. + * + * @author Ben Alex + * @version $Id$ + */ +public class ImmutableManagerImpl extends ApplicationObjectSupport implements ImmutableManager, InitializingBean { + //~ Instance fields ======================================================== + + /** The class that this instance provides services for */ + private Class supportsClass; + private String beanName; + + protected Dao dao; + + //~ Methods ================================================================ + + public ImmutableManagerImpl() { + this.supportsClass = GenericsUtils.getGeneric(getClass()); + if (supportsClass == null) { + if (logger.isWarnEnabled()) { + logger.warn("Could not determine the generics type - you will need to set manually"); + } + } + } + + public void setSupportsClass(Class supportClass) { + this.supportsClass = supportClass; + } + + public Class getSupportsClass() { + return supportsClass; + } + + public Dao getDao() { + return dao; + } + + public void setDao(Dao dao) { + this.dao = dao; + } + + /** + * @return the sort order column to be used by default by the scroll methods + */ + protected String getDefaultSortOrder() { + return "id"; + } + + /** + * Provides hook for custom subclasses to provide initialization behaviour + * + * @throws Exception + */ + protected void doInitManager() throws Exception {} + + public final void afterPropertiesSet() throws Exception { + Assert.notNull(supportsClass, "supportClass is required"); + Assert.isTrue(PersistableEntity.class.isAssignableFrom(supportsClass), + "supportClass is not an implementation of PersistableEntity"); + Assert.notNull(dao, "Dao is null"); + Assert.isTrue(dao.supports(supportsClass), "Dao '" + dao + "' does not support '" + supportsClass + "'"); + doInitManager(); + } + + public List findAll() { + return dao.findAll(); + } + + public List findId(Collection ids) { + Assert.notNull(ids, "Collection of IDs cannot be null"); + Assert.notEmpty(ids, "There must be some values in the Collection list"); + return dao.findId(ids); + } + + public E readId(Serializable id) { + Assert.notNull(id); + return dao.readId(id); + } + + public E readPopulatedId(Serializable id) { + Assert.notNull(id); + return dao.readPopulatedId(id); + } + + public PaginatedList scroll(E value, int firstElement, + int maxElements) { + Assert.notNull(value); + Assert.isInstanceOf(this.supportsClass, value, "Can only scroll with values this manager supports"); + + return dao.scroll(value, firstElement, maxElements, getDefaultSortOrder()); + } + + public PaginatedList scrollPopulated(E value, int firstElement, int maxElements) { + Assert.notNull(value); + Assert.isInstanceOf(this.supportsClass, value, "Can only scroll with values this manager supports"); + + return dao.scrollPopulated(value, firstElement, maxElements, getDefaultSortOrder()); + } + + public PaginatedList scrollWithSubclasses(E value, int firstElement, + int maxElements) { + Assert.notNull(value); + Assert.isInstanceOf(this.supportsClass, value, "Can only scroll with values this manager supports"); + + return dao.scrollWithSubclasses(value, firstElement, maxElements, getDefaultSortOrder()); + } + + public PaginatedList scrollPopulatedWithSubclasses(E value, int firstElement, int maxElements) { + Assert.notNull(value); + Assert.isInstanceOf(this.supportsClass, value, "Can only scroll with values this manager supports"); + + return dao.scrollPopulatedWithSubclasses(value, firstElement, maxElements, getDefaultSortOrder()); + } + + public boolean supports(Class clazz) { + Assert.notNull(clazz); + + return this.supportsClass.equals(clazz); + } + + public void setBeanName(String beanName) { + this.beanName = beanName; + } +} diff --git a/domain/src/main/java/org/acegisecurity/domain/service/Manager.java b/domain/src/main/java/org/acegisecurity/domain/service/Manager.java index 0f493bc02d..4f00ad140e 100644 --- a/domain/src/main/java/org/acegisecurity/domain/service/Manager.java +++ b/domain/src/main/java/org/acegisecurity/domain/service/Manager.java @@ -16,250 +16,20 @@ package net.sf.acegisecurity.domain.service; import net.sf.acegisecurity.domain.PersistableEntity; -import net.sf.acegisecurity.domain.dao.PaginatedList; - -import java.io.Serializable; - -import java.util.Collection; -import java.util.List; /** - * Provides fundamental services layer capabilities for a single concrete {@link - * PersistableEntity}, using JDK 1.5 generics. - * - *

- * This interface provides a remoting protocol compliant approach to accessing - * services layer logic for a given application. A generics-based services - * layer interface decreases development time because the basic CRUD and finder - * operations can be specified in a typesafe fashion that reuses superclass - * code. - *

- * - *

- * It is not envisioned that this interface will provide all services layer - * functions. The significant value of a services layer is the value-add beyond - * simply fronting the DAO or applying validation/binding logic that is better - * situated in the domain object or its validator. The type of value-adds - * expected to be provided by a services layer include incrementing business - * identifiers (eg an invoice number); generating messages for logging/audit - * purposes (thus such messages are at a business transaction level of granularity, - * instead of DAO/persistence granularity where the overall context of the - * the message becomes unclear); updating related domain objects via - * their respective services layer beans (eg an invoice services layer bean - * would call the general journal services layer bean to create the accrual - * accounting entries); making changes to a domain object that requires - * logic that is unsuitable to put into a validator because it extends - * beyond a single domain object instance or requires access to other persistent - * entities (eg computing taxation appliable to an invoice based on a break-down - * of each item on the order, its delivery destination, and the customer); - * producing messages (eg notify another system the invoice was created or - * email the customer via SMTP); provide a layer to locate transaction and - * security configuration; expose a reasonably protocol-independent interface - * to the application that can be used by a variety of web services and - * client types; ensure any returned objects are eagerly loaded to a well-defined - * interface contract etc. - *

- * - *

- * A single Manager implementation will typically exist for each - * {@link net.sf.acegisecurity.domain.PersistableEntity}, particularly given - * a PersistableEntity is allowed to manage multiple - * {@link net.sf.acegisecurity.domain.impl.PersistableValue}s. - * The particular PersistableEntity an implementation supports - * will be expressed by the {@link #supports(Class)} method. - *

- * - *

No other part of the Domain subproject relies on this interface. If - * you would prefer to write your own services layer interfaces from scratch, - * this is not a problem at all. + * Adds a deletion method to UpdatableManager, thus providing CRUD + * use case support. * * @author Ben Alex * @version $Id$ */ -public interface Manager { +public interface Manager extends UpdatableManager { //~ Methods ================================================================ - - /** - * Create a new object, with the current {@link - * PersistableEntity#getInternalId()} value being ignored. - * - * @param value (without the identity property initialized) - * - * @return the value created (with the identity property initialised) - */ - public E create(E value); - - /** - * Saves an existing object to the persistence layer, or creates a new - * object in the persistence layer. Implementations typically rely on - * {@link PersistableEntity#getInternalId()} being non-null - * to differentiate between persistence instances previous saved and those - * requiring initial creation. - * - * @param value to save or update - * - * @return the saved or updated (as appropriate) value - */ - public E createOrUpdate(E value); - /** * Delete an object. * * @param value the value to delete */ public void delete(E value); - - /** - * Return all persistent instances, including subclasses. - * - * @return all persistence instances (an empty List will be - * returned if no matches are found) - */ - public List findAll(); - - /** - * Find a List of PersistableEntitys, searched by - * their identifiers. - * - * @param ids collection of identifiers to locate - * - * @return the values with those identifiers (an empty List - * will be returned if no matches are found) - */ - public List findId(Collection ids); - - /** - * Load a persistent instance by its identifier, although some properties - * may be lazy loaded depending on the underlying DAO implementation and/or - * persistence engine mapping document. - * - * @param id the identifier of the persistent instance desired to be - * retrieved - * - * @return the request item, or null if not found - */ - public E readId(Serializable id); - - /** - * Loads a persistent instance by its identifier, along with any - * lazy loaded properties associated with that instance. - * - * @param id the identifier of the persistent instance desired to be - * retrieved - * - * @return the request item, or null if not found - */ - public E readPopulatedId(Serializable id); - - /** - * Find persistent instances with properties matching those of the passed - * PersistableEntity. - * - *

- * Persistent instances are matched on the basis of query by example. - * Properties whose value is null, empty - * Strings, and any Collections are ignored in - * the query by example evaluation. - *

- * - * @param value parameters to filter on (the class of this object will - * be added to the filter) - * @param firstElement the first result (start at zero to obtain all - * results) - * @param maxElements the maximum number of results desired for this page - * of the result set - * - * @return the requested page of the result list (a properly formed - * PaginatedList is returned if no results match) - */ - public PaginatedList scroll(E value, int firstElement, - int maxElements); - - /** - * Find persistent instances with properties matching those of the passed - * PersistableEntity, with a guarantee the returned results - * will have each of the value class' immediate properties - * initialized. - * - *

- * Persistent instances are matched on the basis of query by example. - * Properties whose value is null, empty - * Strings, and any Collections are ignored in - * the query by example evaluation. - *

- * - * @param value parameters to filter on (the class of this object will - * be added to the filter) - * @param firstElement the first result (start at zero to obtain all - * results) - * @param maxElements the maximum number of results desired for this page - * of the result set - * - * @return the requested page of the result list (a properly formed - * PaginatedList is returned if no results match) - */ - public PaginatedList scrollPopulated(E value, int firstElement, - int maxElements); - - /** - * Find persistent instances with properties matching those of the passed - * PersistableEntity, ignoring the class of the passed - * PersistableEntity (useful if you pass a superclass, as you - * want to find all subclass instances which match). - * - * @param value parameters to filter on (the class of this object will - * NOT be added to the filter) - * @param firstElement the first result (start at zero to obtain all - * results) - * @param maxElements the maximum number of results desired for this page - * of the result set - * - * @return the requested page of the result list (a properly formed - * PaginatedList is returned if no results match) - */ - public PaginatedList scrollWithSubclasses(E value, int firstElement, - int maxElements); - - /** - * Find persistent instances with properties matching those of the passed - * PersistableEntity, ignoring the class of the passed - * PersistableEntity (useful if you pass a superclass, as you - * want to find all subclass instances which match). Guarantees the returned - * results will have each of the DAO's supports class' immediate - * properties initialized. - * - * @param value parameters to filter on (the class of this object will - * NOT be added to the filter) - * @param firstElement the first result (start at zero to obtain all - * results) - * @param maxElements the maximum number of results desired for this page - * of the result set - * - * @return the requested page of the result list (a properly formed - * PaginatedList is returned if no results match) - */ - public PaginatedList scrollPopulatedWithSubclasses(E value, int firstElement, - int maxElements); - - /** - * Indicates whether the DAO instance provides persistence services for the - * specified class. - * - * @param clazz to test, which should be an implementation of - * PersistableEntity - * - * @return true or false, indicating whether or - * not the passed class is supported by this DAO instance - */ - public boolean supports(Class clazz); - - /** - * Update an object. - * - * @param value to update, with the PersistableEntity having a - * non-null identifier - * - * @return the updated value - */ - public E update(E value); } diff --git a/domain/src/main/java/org/acegisecurity/domain/service/ManagerImpl.java b/domain/src/main/java/org/acegisecurity/domain/service/ManagerImpl.java index 99d22e3665..4c8d7b3466 100644 --- a/domain/src/main/java/org/acegisecurity/domain/service/ManagerImpl.java +++ b/domain/src/main/java/org/acegisecurity/domain/service/ManagerImpl.java @@ -15,18 +15,8 @@ package net.sf.acegisecurity.domain.service; -import java.io.Serializable; -import java.util.Collection; -import java.util.List; - import net.sf.acegisecurity.domain.PersistableEntity; -import net.sf.acegisecurity.domain.dao.Dao; -import net.sf.acegisecurity.domain.dao.PaginatedList; -import net.sf.acegisecurity.domain.util.GenericsUtils; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.context.support.ApplicationObjectSupport; -import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; /** @@ -35,89 +25,7 @@ import org.springframework.util.Assert; * @author Ben Alex * @version $Id$ */ -@Transactional -public class ManagerImpl extends ApplicationObjectSupport implements Manager, InitializingBean { - //~ Instance fields ======================================================== - - /** The class that this instance provides services for */ - private Class supportsClass; - private String beanName; - - protected Dao dao; - - //~ Methods ================================================================ - - public ManagerImpl() { - this.supportsClass = GenericsUtils.getGeneric(getClass()); - if (supportsClass == null) { - if (logger.isWarnEnabled()) { - logger.warn("Could not determine the generics type - you will need to set manually"); - } - } - } - - public void setSupportsClass(Class supportClass) { - this.supportsClass = supportClass; - } - - public Class getSupportsClass() { - return supportsClass; - } - - public Dao getDao() { - return dao; - } - - public void setDao(Dao dao) { - this.dao = dao; - } - - /** - * @return the sort order column to be used by default by the scroll methods - */ - protected String getDefaultSortOrder() { - return "id"; - } - - /** - * Provides hook for custom subclasses to provide initialization behaviour - * - * @throws Exception - */ - protected void doInitManager() throws Exception {} - - public final void afterPropertiesSet() throws Exception { - Assert.notNull(supportsClass, "supportClass is required"); - Assert.isTrue(PersistableEntity.class.isAssignableFrom(supportsClass), - "supportClass is not an implementation of PersistableEntity"); - Assert.notNull(dao, "Dao is null"); - Assert.isTrue(dao.supports(supportsClass), "Dao '" + dao + "' does not support '" + supportsClass + "'"); - doInitManager(); - } - - public E create(E value) { - Assert.notNull(value); - if (logger.isDebugEnabled()) { - logger.debug("Creating: " + value); - } - return dao.create(value); - } - - /** - * Delegates to the appropriate services layer method (not the DAO). - */ - public E createOrUpdate(E value) { - Assert.notNull(value); - if (logger.isDebugEnabled()) { - logger.debug("CreatingOrUpdating: " + value); - } - if (value.getInternalId() == null) { - return create(value); - } else { - return update(value); - } - } - +public class ManagerImpl extends UpdatableManagerImpl implements Manager { public void delete(E value) { Assert.notNull(value); if (logger.isDebugEnabled()) { @@ -126,71 +34,4 @@ public class ManagerImpl extends ApplicationObjectS dao.delete(value); } - public List findAll() { - return dao.findAll(); - } - - public List findId(Collection ids) { - Assert.notNull(ids, "Collection of IDs cannot be null"); - Assert.notEmpty(ids, "There must be some values in the Collection list"); - return dao.findId(ids); - } - - public E readId(Serializable id) { - Assert.notNull(id); - return dao.readId(id); - } - - public E readPopulatedId(Serializable id) { - Assert.notNull(id); - return dao.readPopulatedId(id); - } - - public PaginatedList scroll(E value, int firstElement, - int maxElements) { - Assert.notNull(value); - Assert.isInstanceOf(this.supportsClass, value, "Can only scroll with values this manager supports"); - - return dao.scroll(value, firstElement, maxElements, getDefaultSortOrder()); - } - - public PaginatedList scrollPopulated(E value, int firstElement, int maxElements) { - Assert.notNull(value); - Assert.isInstanceOf(this.supportsClass, value, "Can only scroll with values this manager supports"); - - return dao.scrollPopulated(value, firstElement, maxElements, getDefaultSortOrder()); - } - - public PaginatedList scrollWithSubclasses(E value, int firstElement, - int maxElements) { - Assert.notNull(value); - Assert.isInstanceOf(this.supportsClass, value, "Can only scroll with values this manager supports"); - - return dao.scrollWithSubclasses(value, firstElement, maxElements, getDefaultSortOrder()); - } - - public PaginatedList scrollPopulatedWithSubclasses(E value, int firstElement, int maxElements) { - Assert.notNull(value); - Assert.isInstanceOf(this.supportsClass, value, "Can only scroll with values this manager supports"); - - return dao.scrollPopulatedWithSubclasses(value, firstElement, maxElements, getDefaultSortOrder()); - } - - public boolean supports(Class clazz) { - Assert.notNull(clazz); - - return this.supportsClass.equals(clazz); - } - - public E update(E value) { - Assert.notNull(value); - if (logger.isDebugEnabled()) { - logger.debug("Updating: " + value); - } - return dao.update(value); - } - - public void setBeanName(String beanName) { - this.beanName = beanName; - } } diff --git a/domain/src/main/java/org/acegisecurity/domain/service/UpdatableManager.java b/domain/src/main/java/org/acegisecurity/domain/service/UpdatableManager.java new file mode 100644 index 0000000000..e9baa79fc9 --- /dev/null +++ b/domain/src/main/java/org/acegisecurity/domain/service/UpdatableManager.java @@ -0,0 +1,51 @@ +/* Copyright 2004, 2005 Acegi Technology Pty Limited + * + * 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. + */ + +package net.sf.acegisecurity.domain.service; + +import net.sf.acegisecurity.domain.PersistableEntity; + +/** + * Adds update (but no delete) methods to the CreatableManager. + * + * @author Ben Alex + * @version $Id$ + */ +public interface UpdatableManager extends CreatableManager { + //~ Methods ================================================================ + + /** + * Saves an existing object to the persistence layer, or creates a new + * object in the persistence layer. Implementations typically rely on + * {@link PersistableEntity#getInternalId()} being non-null + * to differentiate between persistence instances previous saved and those + * requiring initial creation. + * + * @param value to save or update + * + * @return the saved or updated (as appropriate) value + */ + public E createOrUpdate(E value); + + /** + * Update an object. + * + * @param value to update, with the PersistableEntity having a + * non-null identifier + * + * @return the updated value + */ + public E update(E value); +} diff --git a/domain/src/main/java/org/acegisecurity/domain/service/UpdatableManagerImpl.java b/domain/src/main/java/org/acegisecurity/domain/service/UpdatableManagerImpl.java new file mode 100644 index 0000000000..48fd2b0588 --- /dev/null +++ b/domain/src/main/java/org/acegisecurity/domain/service/UpdatableManagerImpl.java @@ -0,0 +1,52 @@ +/* Copyright 2004, 2005 Acegi Technology Pty Limited + * + * 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. + */ + +package net.sf.acegisecurity.domain.service; + +import net.sf.acegisecurity.domain.PersistableEntity; + +import org.springframework.util.Assert; + +/** + * Base {@link UpdatableManager} implementation. + * + * @author Ben Alex + * @version $Id$ + */ +public class UpdatableManagerImpl extends CreatableManagerImpl implements UpdatableManager { + + public E update(E value) { + Assert.notNull(value); + if (logger.isDebugEnabled()) { + logger.debug("Updating: " + value); + } + return dao.update(value); + } + + /** + * Delegates to the appropriate services layer method (not the DAO). + */ + public E createOrUpdate(E value) { + Assert.notNull(value); + if (logger.isDebugEnabled()) { + logger.debug("CreatingOrUpdating: " + value); + } + if (value.getInternalId() == null) { + return create(value); + } else { + return update(value); + } + } +}