Java tutorial
/* * * Copyright 2013 Entando S.r.l. (http://www.entando.com) All rights reserved. * * This file is part of Entando software. * Entando is a free software; * You can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) as published by the Free Software Foundation; version 2. * * See the file License for the specific language governing permissions * and limitations under the License * * * * Copyright 2013 Entando S.r.l. (http://www.entando.com) All rights reserved. * */ package com.agiletec.aps.system.common.entity; import java.io.StringReader; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.apache.commons.beanutils.BeanComparator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xml.sax.InputSource; import com.agiletec.aps.system.common.AbstractService; import com.agiletec.aps.system.common.entity.event.EntityTypesChangingEvent; import com.agiletec.aps.system.common.entity.event.ReloadingEntitiesReferencesEvent; import com.agiletec.aps.system.common.entity.event.ReloadingEntitiesReferencesObserver; import com.agiletec.aps.system.common.entity.loader.AttributeDisablingCodesLoader; import com.agiletec.aps.system.common.entity.loader.AttributeRolesLoader; import com.agiletec.aps.system.common.entity.model.ApsEntityRecord; import com.agiletec.aps.system.common.entity.model.EntitySearchFilter; import com.agiletec.aps.system.common.entity.model.IApsEntity; import com.agiletec.aps.system.common.entity.model.attribute.AttributeInterface; import com.agiletec.aps.system.common.entity.model.attribute.AttributeRole; import com.agiletec.aps.system.common.entity.parse.EntityHandler; import com.agiletec.aps.system.common.entity.parse.IApsEntityDOM; import com.agiletec.aps.system.common.entity.parse.IEntityTypeDOM; import com.agiletec.aps.system.common.entity.parse.IEntityTypeFactory; import com.agiletec.aps.system.exception.ApsSystemException; import com.agiletec.aps.system.services.category.ICategoryManager; import com.agiletec.aps.util.DateConverter; /** * This abstract service must be extended in all those services that make use of ApsEntities. * By default, extending the manager, it is necessary to implement the method that returns the specific * category manager and, in the definition of the Spring service, the configuration item where to look * for the definitions of the Entity Types handled by the service. * @author E.Santoboni */ public abstract class ApsEntityManager extends AbstractService implements IEntityManager, IEntityTypesConfigurer, ReloadingEntitiesReferencesObserver { private static final Logger _logger = LoggerFactory.getLogger(ApsEntityManager.class); /** * Initialize the service by loading the Entity Types form the configuration. * @throws Exception If errors are detected during the service initialization. */ @Override public void init() throws Exception { this._entityDom.setRootElementName(this.getXmlAttributeRootElementName()); String entityManagerName = super.getName(); this._entityTypes = this._entityTypeFactory.getEntityTypes(this.getEntityClass(), this.getConfigItemName(), this.getEntityTypeDom(), entityManagerName, this.getEntityDom()); _logger.debug("{} : inizializated {} entity types", this.getName(), this._entityTypes.size()); } @Override public void refresh() throws Throwable { super.refresh(); this._attributeDisablingCodes = null; this._attributeRoles = null; } @Override public Map<String, String> getAttributeDisablingCodes() { if (null != this._attributeDisablingCodes) { //codes already loaded return this._attributeDisablingCodes; } //codes not loaded yet AttributeDisablingCodesLoader loader = new AttributeDisablingCodesLoader(); this._attributeDisablingCodes = loader.extractDisablingCodes(this.getAttributeDisablingCodesFileName(), super.getBeanFactory(), this); Map<String, String> clone = new HashMap<String, String>(); clone.putAll(this._attributeDisablingCodes); return clone; } @Override public List<AttributeRole> getAttributeRoles() { if (null != this._attributeRoles) { //roles already loaded return this.getOrderedAttributeRoles(); } //roles not loaded yet this.initAttributeRoles(); return this.getOrderedAttributeRoles(); } protected void initAttributeRoles() { this._attributeRoles = new HashMap<String, AttributeRole>(); AttributeRolesLoader loader = new AttributeRolesLoader(); this._attributeRoles = loader.extractAttributeRoles(this.getAttributeRolesFileName(), super.getBeanFactory(), this); } private List<AttributeRole> getOrderedAttributeRoles() { List<AttributeRole> roles = new ArrayList<AttributeRole>(this._attributeRoles.size()); Iterator<AttributeRole> iter = this._attributeRoles.values().iterator(); while (iter.hasNext()) { AttributeRole role = iter.next(); roles.add(role.clone()); } BeanComparator comparator = new BeanComparator("name"); Collections.sort(roles, comparator); return roles; } @Override public AttributeRole getAttributeRole(String roleName) { if (null == this._attributeRoles) { this.initAttributeRoles(); } AttributeRole role = this._attributeRoles.get(roleName); if (null != role) { return role.clone(); } return null; } /** * Create and populate the entity as specified by its type and XML definition. * @param entityTypeCode The Entity Type code. * @param xml The XML of the associated entity. * @return The populated entity. * @throws ApsSystemException If errors detected while retrieving the entity. */ protected IApsEntity createEntityFromXml(String entityTypeCode, String xml) throws ApsSystemException { try { IApsEntity entityPrototype = this.getEntityPrototype(entityTypeCode); SAXParserFactory parseFactory = SAXParserFactory.newInstance(); SAXParser parser = parseFactory.newSAXParser(); InputSource is = new InputSource(new StringReader(xml)); EntityHandler handler = this.getEntityHandler(); handler.initHandler(entityPrototype, this.getXmlAttributeRootElementName(), this.getCategoryManager()); parser.parse(is, handler); return entityPrototype; } catch (Throwable t) { _logger.error("Error detected while creating the entity. typecode: {} - xml: {}", entityTypeCode, xml, t); //ApsSystemUtils.logThrowable(t, this, "createEntityFromXml"); throw new ApsSystemException("Error detected while creating the entity", t); } } /** * Indicates whether the service makes use of the search engine. * Default value: false. * @return true if the services uses the search engine, false otherwise. */ @Override public boolean isSearchEngineUser() { return false; } /** * Create an entity prototype given the relative code. * This method is for those managers that extend the ApsEntityManager. * @param typeCode The entity code. * @return The prototype of requested entity. * @deprecated From jAPS 2.0 version 2.0.9, use getEntityPrototype(String typeCode) */ protected IApsEntity createEntityPrototype(String typeCode) { return this.getEntityPrototype(typeCode); } @Override public IApsEntity getEntityPrototype(String typeCode) { IApsEntity entityType = this.getEntityTypes().get(typeCode); if (null == entityType) { return null; } return entityType.getEntityPrototype(); } @Override public Map<String, IApsEntity> getEntityPrototypes() { Collection<IApsEntity> entityTypes = this._entityTypes.values(); Map<String, IApsEntity> entityTypesMap = new HashMap<String, IApsEntity>(entityTypes.size()); Iterator<IApsEntity> iter = entityTypes.iterator(); while (iter.hasNext()) { IApsEntity entityType = iter.next(); IApsEntity clone = entityType.getEntityPrototype(); entityTypesMap.put(clone.getTypeCode(), clone); } return entityTypesMap; } /** * Add a new entity prototype on the catalog. * @param entityType The entity type to add. * @throws ApsSystemException In case of error. */ @Override public void addEntityPrototype(IApsEntity entityType) throws ApsSystemException { if (null == entityType) { throw new ApsSystemException("Invalid entity type to add"); } Map<String, IApsEntity> newEntityTypes = new HashMap<String, IApsEntity>(this._entityTypes); newEntityTypes.put(entityType.getTypeCode(), entityType); this.updateEntityPrototypes(newEntityTypes); this.notifyEntityTypesChanging(null, entityType, EntityTypesChangingEvent.INSERT_OPERATION_CODE); } /** * Update an entity prototype on the catalog. * @param entityType The entity type to update. * @throws ApsSystemException In case of error. */ @Override public void updateEntityPrototype(IApsEntity entityType) throws ApsSystemException { if (null == entityType) { throw new ApsSystemException("Invalid entity type to update"); } IApsEntity oldEntityType = this._entityTypes.get(entityType.getTypeCode()); if (null == oldEntityType) { throw new ApsSystemException( "No entity type to update with code '" + entityType.getTypeCode() + "' where found"); } Map<String, IApsEntity> newEntityTypes = new HashMap<String, IApsEntity>(this._entityTypes); newEntityTypes.put(entityType.getTypeCode(), entityType); this.updateEntityPrototypes(newEntityTypes); this.verifyReloadingNeeded(oldEntityType, entityType); this.notifyEntityTypesChanging(oldEntityType, entityType, EntityTypesChangingEvent.UPDATE_OPERATION_CODE); } protected void verifyReloadingNeeded(IApsEntity oldEntityType, IApsEntity newEntityType) { if (this.getStatus(newEntityType.getTypeCode()) == STATUS_NEED_TO_RELOAD_REFERENCES) { return; } List<AttributeInterface> attributes = oldEntityType.getAttributeList(); for (int i = 0; i < attributes.size(); i++) { AttributeInterface oldAttribute = attributes.get(i); AttributeInterface newAttribute = (AttributeInterface) newEntityType .getAttribute(oldAttribute.getName()); if ((oldAttribute.isSearchable() && null == newAttribute) || (null != newAttribute && oldAttribute.isSearchable() != newAttribute.isSearchable())) { this.setStatus(IEntityManager.STATUS_NEED_TO_RELOAD_REFERENCES, oldEntityType.getTypeCode()); return; } String[] oldRoles = (null != oldAttribute.getRoles()) ? oldAttribute.getRoles() : new String[0]; String[] newRoles = (null != newAttribute && null != newAttribute.getRoles()) ? newAttribute.getRoles() : new String[0]; if ((newRoles.length == 0 && oldRoles.length == 0)) { continue; } else if (newRoles.length != oldRoles.length) { this.setStatus(IEntityManager.STATUS_NEED_TO_RELOAD_REFERENCES, oldEntityType.getTypeCode()); return; } else { List<String> oldRolesList = Arrays.asList(oldRoles); List<String> newRolesList = Arrays.asList(newRoles); for (int j = 0; j < newRolesList.size(); j++) { String roleName = newRolesList.get(j); if (!oldRolesList.contains(roleName)) { this.setStatus(IEntityManager.STATUS_NEED_TO_RELOAD_REFERENCES, oldEntityType.getTypeCode()); return; } } } } } /** * Remove an entity type from the catalog. * @param entityTypeCode The code of the entity type to remove. * @throws ApsSystemException In case of error. */ @Override public void removeEntityPrototype(String entityTypeCode) throws ApsSystemException { IApsEntity entityTypeToRemove = this._entityTypes.get(entityTypeCode); if (null == entityTypeToRemove) { throw new ApsSystemException("No entity type to remove with code '" + entityTypeCode + "' were found"); } Map<String, IApsEntity> newEntityTypes = new HashMap<String, IApsEntity>(this._entityTypes); newEntityTypes.remove(entityTypeCode); this.updateEntityPrototypes(newEntityTypes); this.notifyEntityTypesChanging(entityTypeToRemove, null, EntityTypesChangingEvent.REMOVE_OPERATION_CODE); } /** * Update entity prototypes * @param newEntityTypes the map, indexed by code, containing the new entities. * @throws ApsSystemException If errors are detected during the process. */ private void updateEntityPrototypes(Map<String, IApsEntity> newEntityTypes) throws ApsSystemException { try { this._entityTypeFactory.updateEntityTypes(newEntityTypes, this.getConfigItemName(), this.getEntityTypeDom()); this.refresh(); } catch (Throwable t) { //ApsSystemUtils.logThrowable(t, this, "updateEntityPrototypes"); _logger.error("Error detected while updating entity prototypes", t); throw new ApsSystemException("Error detected while updating entity prototypes", t); } } private void notifyEntityTypesChanging(IApsEntity oldEntityType, IApsEntity newEntityType, int operationCode) throws ApsSystemException { EntityTypesChangingEvent event = new EntityTypesChangingEvent(); event.setOperationCode(operationCode); event.setNewEntityType(newEntityType); event.setOldEntityType(oldEntityType); event.setEntityManagerName(this.getName()); this.notifyEvent(event); } /** * Return the map of the Entity Types managed by the service. * @return The map of the Entity Types indexed by the type code. */ protected Map<String, IApsEntity> getEntityTypes() { return this._entityTypes; } @Override public Map<String, AttributeInterface> getEntityAttributePrototypes() { Collection<AttributeInterface> attributes = this.getEntityTypeDom().getAttributeTypes().values(); Map<String, AttributeInterface> attributeMap = new HashMap<String, AttributeInterface>(attributes.size()); Iterator<AttributeInterface> iter = attributes.iterator(); while (iter.hasNext()) { AttributeInterface attributeInterface = iter.next(); AttributeInterface clone = (AttributeInterface) attributeInterface.getAttributePrototype(); attributeMap.put(clone.getType(), clone); } return attributeMap; } /** * Set up the Entity Types factory. * This method is used and hereby found in the spring XML configuration of the service. * By default, the definition of the abstract service in the Spring configuration presents a * standard factory; such definition must be substituted in the declaration of the service if * specific operations are required by the particular structure of the Entity Type to manage. * @param entityTypeFactory The factory of Entity Types. */ public void setEntityTypeFactory(IEntityTypeFactory entityTypeFactory) { this._entityTypeFactory = entityTypeFactory; } /** * This method is used and hereby found in the spring XML configuration of the service. * By default, the declaration of the abstract service in the Spring configuration presents a * standard class (ApsEntity); this class must be substituted in the definition of the service * if a different class, which extends the standard ApsEntity, must be used. * This method checks the validity of the class. * @param className The name of the entity class. */ public void setEntityClassName(String className) { try { this._entityClass = Class.forName(className); Class check = this._entityClass; do { Class[] interfaces = check.getInterfaces(); for (int j = 0; j < interfaces.length; j++) { if (interfaces[j].equals(IApsEntity.class)) return; } check = check.getSuperclass(); } while (!check.equals(Object.class)); throw new RuntimeException("Invalid entity class"); } catch (ClassNotFoundException e) { _logger.error("Errore creating the entity class", e); //ApsSystemUtils.logThrowable(e, this, "setEntityClassName","Error detected while creating the entity class"); throw new RuntimeException("Error creating the entity class", e); } } /** * @deprecated From jAPS 2.0 version 2.0.9, use setEntityClassName */ public void setEntityClass(String className) { this.setEntityClassName(className); } @Override public Class getEntityClass() { return this._entityClass; } /** * Return The name of the configuration item where to extract the definition of the Entity types. * @param confItemName The name of the configuration item. */ protected String getConfigItemName() { return this._configItemName; } /** * Prepare the configuration item where to extract the definition of the various Entity types * managed by the service. * @param confItemName The name of the configuration item where to extract the definition * of the Entity types */ public void setConfigItemName(String confItemName) { this._configItemName = confItemName; } protected IEntityTypeDOM getEntityTypeDom() { return this._entityTypeDom; } /** * Prepare the DOM class that interprets the XML defining the various Entity Types managed by the service. * This method is used and hereby found in the Spring XML configuration of the service. * By default, the declaration of the abstract service contains the standard DOM class, namely the EntityTypeDOM; * this definition can be substituted in the declaration of the service if a different DOM class, * implementing the IEntityTypeDOM interface, is used. This is, for example, to interpret * customized Entity Types -all implementing the ApsEntity- in a new service. * @param entityTypeDom The DOM class that parses the XML configuring the Entity Types. */ public void setEntityTypeDom(IEntityTypeDOM entityTypeDom) { this._entityTypeDom = entityTypeDom; } /** * Set up the name of the root attribute in the XML representing the single entity. * This method is used and found in the Spring XML definition of the service. * By default, the definition of the abstract service in the Spring configuration, presents the * name "entity"; this definition can be substituted in the implementation of the service if a new name is used. * @param xmlAttributeRootElementName The name of the root attribute. */ public void setXmlAttributeRootElementName(String xmlAttributeRootElementName) { this._xmlAttributeRootElementName = xmlAttributeRootElementName; } protected String getXmlAttributeRootElementName() { return this._xmlAttributeRootElementName; } /** * Set up the handler class that parses the XML defining single entities. * This method is used and hereby found in the Spring XML configuration of the service. * The definition of the abstract service in the Spring configuration presents a default * handler class, namely the EntityHandler; this definition can be changed in the declaration of the service * if a particular handler, which extends EntityHandler, is used to parse specific entities. * The class of such entities must extend the ApsEntity class to be correctly managed by the service. * @param entityHandler The handler class that parses the XML of the single entities. */ public void setEntityHandler(EntityHandler entityHandler) { this._entityHandler = entityHandler; } /** * Return the handler class that parses the single entity. * This method returns a prototype ready to be used to parse an entity. * @return The handler class that parses the XML of the entity. */ protected EntityHandler getEntityHandler() { return this._entityHandler.getHandlerPrototype(); } protected IApsEntityDOM getEntityDom() { return this._entityDom; } /** * Set the DOM class that generates the XML that represents a single entity. * This method is used and hereby found in the Spring XML configuration of the service. * By default, the definition of the abstract service in the Spring configuration, presents a standard * DOM class, namely the ApsEntityDOM; this definition can be substituted in the declaration of the service * if a different DOM class, implementing the IApsEntityDOM interface, is used to generate * the XML of particular entities. Such entities are mapped to a class that must extend, * as usual, the ApsEntity class. */ public void setEntityDom(IApsEntityDOM entityDom) { this._entityDom = entityDom; } /** * Search entities. * @param filters The filters used to find an sort the entities ID that match * the given criteria. * @return The list of the IDs found. * @throws ApsSystemException In case of error. */ @Override public List<String> searchId(EntitySearchFilter[] filters) throws ApsSystemException { List<String> idList = null; try { idList = this.getEntitySearcherDao().searchId(filters); } catch (Throwable t) { _logger.error("Error detected while searching entities", t); //ApsSystemUtils.logThrowable(t, this, "searchId"); throw new ApsSystemException("Error detected while searching entities", t); } return idList; } /** * Search entities. * @param typeCode The code of the Entity Types to look for. * @param filters The search filters to apply to find and sort the ID found. * @return The list of the ID found. * @throws ApsSystemException In case of error. */ @Override public List<String> searchId(String typeCode, EntitySearchFilter[] filters) throws ApsSystemException { List<String> idList = null; try { idList = this.getEntitySearcherDao().searchId(typeCode, filters); } catch (Throwable t) { _logger.error("Error detected while searching entities with typeCode {}", typeCode, t); //ApsSystemUtils.logThrowable(t, this, "searchId"); throw new ApsSystemException("Error detected while searching entities", t); } return idList; } @Override public List<ApsEntityRecord> searchRecords(EntitySearchFilter[] filters) throws ApsSystemException { List<ApsEntityRecord> records = null; try { records = this.getEntitySearcherDao().searchRecords(filters); } catch (Throwable t) { _logger.error("Error searching entity records", t); //ApsSystemUtils.logThrowable(t, this, "searchRecords"); throw new ApsSystemException("Error searching entity records", t); } return records; } @Override public void reloadEntitiesReferences(ReloadingEntitiesReferencesEvent event) { try { String typeCode = null; this.reloadEntitiesReferences(typeCode); } catch (Throwable t) { _logger.error("Error while refreshing entity refrences", t); //ApsSystemUtils.logThrowable(t, this, "reloadEntitiesReferences", "Error while refreshing entity refrences"); } } @Override public Thread reloadEntitiesReferences(String typeCode) { ReloadingReferencesThread reloadThread = null; if (this.getStatus() == STATUS_READY || this.getStatus(typeCode) != STATUS_RELOADING_REFERENCES_IN_PROGRESS) { try { reloadThread = new ReloadingReferencesThread(this, typeCode); String threadName = RELOAD_REFERENCES_THREAD_NAME_PREFIX + this.getName() + "_" + DateConverter.getFormattedDate(new Date(), "yyyyMMddHHmmss"); reloadThread.setName(threadName); reloadThread.start(); _logger.info("Reloading references started"); } catch (Throwable t) { throw new RuntimeException("Error while starting up the reference reload procedure", t); } } else { _logger.info("Reloading entity references suspended: status {}", this.getStatus(typeCode)); } return reloadThread; } /** * Reload the entity references. * @param typeCode The type Code of entities to reload references. If null, will reload all entities. * @throws ApsSystemException In case of error. */ protected synchronized void reloadEntitySearchReferencesByType(String typeCode) throws ApsSystemException { if (null == typeCode) { throw new ApsSystemException("Error: invalid type code detected"); } this.setStatus(ApsEntityManager.STATUS_RELOADING_REFERENCES_IN_PROGRESS, typeCode); try { EntitySearchFilter filter = new EntitySearchFilter(ENTITY_TYPE_CODE_FILTER_KEY, false, typeCode, false); EntitySearchFilter[] filters = { filter }; List<String> entitiesId = this.getEntitySearcherDao().searchId(filters); for (int i = 0; i < entitiesId.size(); i++) { String entityId = (String) entitiesId.get(i); this.reloadEntityReferences(entityId); } } catch (Throwable t) { _logger.error("Error reloading entity references of type: {}", typeCode, t); //ApsSystemUtils.logThrowable(t, this, "reloadEntitySearchReferencesByType"); throw new ApsSystemException("Error reloading entity references of type: " + typeCode, t); } finally { this.setStatus(ApsEntityManager.STATUS_READY, typeCode); } } protected void reloadEntityReferences(String entityId) { try { IApsEntity entity = this.getEntity(entityId); if (entity != null) { this.getEntityDao().reloadEntitySearchRecords(entityId, entity); } _logger.info("Entities search references reloaded {}", entityId); } catch (Throwable t) { _logger.error("Error reloading the entities search references: {}", entityId, t); //ApsSystemUtils.logThrowable(t, this, "reloadEntityReferences", "Error reloading the entities search references: " + entityId); } } /** * Load the complete list of the entities. * @return The complete list of entity IDs. * @throws ApsSystemException In case of error. * @deprecated From jAPS 2.0 version 2.0.9, use {@link IEntitySearcherDAO} searchId(EntitySearchFilter[]) method */ protected List<String> getAllEntityId() throws ApsSystemException { List<String> entitiesId = new ArrayList<String>(); try { entitiesId = this.getEntityDao().getAllEntityId(); } catch (Throwable t) { _logger.error("Error while loading the complete list of entity IDs", t); //ApsSystemUtils.logThrowable(t, this, "getAllEntityId"); throw new ApsSystemException("Error while loading the complete list of entity IDs", t); } return entitiesId; } /** * Return the stutus of the desired entity. If nell it returns the general status. * @param typeCode The Entity type to get the status from. It may be null. * @return The status of the desidered entity. */ @Override public int getStatus(String typeCode) { if (typeCode == null) { return this.getStatus(); } Integer status = this._typesStatus.get(typeCode); if (status != null) { return status.intValue(); } return STATUS_READY; } @Override public int getStatus() { if (this._typesStatus.containsValue(new Integer(STATUS_RELOADING_REFERENCES_IN_PROGRESS))) { return STATUS_RELOADING_REFERENCES_IN_PROGRESS; } else if (this._typesStatus.containsValue(new Integer(STATUS_NEED_TO_RELOAD_REFERENCES))) { return STATUS_NEED_TO_RELOAD_REFERENCES; } return STATUS_READY; } protected String getAttributeRolesFileName() { if (null == this._attributeRolesFileName) { return DEFAULT_ATTRIBUTE_ROLES_FILE_NAME; } return _attributeRolesFileName; } public void setAttributeRolesFileName(String attributeRolesFileName) { this._attributeRolesFileName = attributeRolesFileName; } protected String getAttributeDisablingCodesFileName() { if (null == this._attributeDisablingCodesFileName) { return DEFAULT_ATTRIBUTE_DISABLING_CODES_FILE_NAME; } return _attributeDisablingCodesFileName; } public void setAttributeDisablingCodesFileName(String disablingCodesFileName) { this._attributeDisablingCodesFileName = disablingCodesFileName; } /** * Imposta lo stato del tipo di entit dato. Se null imposta lo stato generale. * Set up the status of the given entity. If null it sets up the overall status. * @param status The status to set up. * @param typeCode The Entity Type where to apply the new status. If null it sets up the * general status. */ protected void setStatus(int status, String typeCode) { this._typesStatus.put(typeCode, new Integer(status)); } protected List<String> getEntityTypeCodes() { return new ArrayList<String>(this._entityTypes.keySet()); } /** * Return the category manager used by the entities managed by the service. * @return The category manager used by the entities. */ protected ICategoryManager getCategoryManager() { return _categoryManager; } public void setCategoryManager(ICategoryManager categoryManager) { this._categoryManager = categoryManager; } /** * Return the DAO to access the entity database with. * @return The entity DAO. */ protected abstract IEntityDAO getEntityDao(); /** * Return the DAO used to search among entities. * @return TheDAO used to search entities. */ protected abstract IEntitySearcherDAO getEntitySearcherDao(); /** * Map of the entity prototypes, indexed by the type code. */ private Map<String, IApsEntity> _entityTypes; private IEntityTypeFactory _entityTypeFactory; private Class _entityClass; private String _configItemName; private IEntityTypeDOM _entityTypeDom; private EntityHandler _entityHandler; private String _xmlAttributeRootElementName; private IApsEntityDOM _entityDom; private ICategoryManager _categoryManager; private Map<String, Integer> _typesStatus = new HashMap<String, Integer>(); private Map<String, AttributeRole> _attributeRoles = null; private Map<String, String> _attributeDisablingCodes = null; private String _attributeRolesFileName; private String _attributeDisablingCodesFileName; /** * Prefix of the thread used for references reloading. */ public static final String RELOAD_REFERENCES_THREAD_NAME_PREFIX = "RELOAD_REFERENCES_INDEX_"; }