package org.sigmah.shared.dto; /* * #%L * Sigmah * %% * Copyright (C) 2010 - 2016 URD * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import org.sigmah.client.util.ToStringBuilder; import org.sigmah.shared.dto.base.AbstractModelDataEntityDTO; import org.sigmah.shared.dto.base.mapping.CustomMappingField; import org.sigmah.shared.dto.base.mapping.IsMappingMode; import org.sigmah.shared.dto.base.mapping.MappingField; import org.sigmah.shared.dto.element.FlexibleElementDTO; import org.sigmah.shared.dto.layout.LayoutConstraintDTO; import org.sigmah.shared.dto.layout.LayoutDTO; import org.sigmah.shared.dto.layout.LayoutGroupDTO; import org.sigmah.shared.dto.logframe.LogFrameModelDTO; import org.sigmah.shared.dto.profile.ProfileDTO; import org.sigmah.shared.dto.referential.ElementTypeEnum; import org.sigmah.shared.dto.referential.ProjectModelStatus; import org.sigmah.shared.dto.referential.ProjectModelType; /** * ProjectModelDTO. * * @author Denis Colliot (dcolliot@ideia.fr) (v2.0) */ public class ProjectModelDTO extends AbstractModelDataEntityDTO<Integer> implements IsModel { /** * Serial version UID. */ private static final long serialVersionUID = 8508466949743884046L; /** * DTO corresponding entity name. */ public static final String ENTITY_NAME = "ProjectModel"; // DTO attributes keys. public static final String NAME = "name"; public static final String STATUS = "status"; public static final String VISIBILITIES = "visibilities"; public static final String ROOT_PHASE_MODEL = "rootPhaseModel"; public static final String PHASE_MODELS = "phaseModels"; public static final String PROJECT_BANNER = "projectBanner"; public static final String PROJECT_DETAILS = "projectDetails"; public static final String LOG_FRAME_MODEL = "logFrameModel"; public static final String MAINTENANCE_DATE = "dateMaintenance"; public static final String UNDER_MAINTENANCE = "underMaintenance"; public static final String DEFAULT_TEAM_MEMBER_PROFILES = "defaultTeamMemberProfiles"; /** * Mapping configurations. * * @author Denis Colliot (dcolliot@ideia.fr) (v2.0) */ public static enum Mode implements IsMappingMode { /** * Base mapping retrieving only project base data (no related DTO). */ BASE( new MappingField(VISIBILITIES), new MappingField(ROOT_PHASE_MODEL), new MappingField(PHASE_MODELS), new MappingField(PROJECT_BANNER), new MappingField(PROJECT_DETAILS), new MappingField(LOG_FRAME_MODEL)), /** * In addition to base data, this mapping includes: * <ul> * <li>{@link ProjectModelDTO#VISIBILITIES}</li> * </ul> */ WITH_VISIBILITIES( new MappingField(ROOT_PHASE_MODEL), new MappingField(PHASE_MODELS), new MappingField(PROJECT_BANNER), new MappingField(PROJECT_DETAILS), new MappingField(LOG_FRAME_MODEL)), /** * In addition to base data, this mapping includes: * <ul> * <li>{@link ProjectModelDTO#VISIBILITIES}</li> * <li>{@link ProjectModelDTO#PROJECT_BANNER}</li> * </ul> */ WITH_VISIBILITIES_AND_BANNER(new MappingField(ROOT_PHASE_MODEL), new MappingField(PHASE_MODELS), new MappingField(PROJECT_DETAILS), new MappingField( LOG_FRAME_MODEL)), /** * Mapping all data */ ALL(), ; private final CustomMappingField[] customFields; private final MappingField[] excludedFields; private Mode(final MappingField... excludedFields) { this(null, excludedFields); } private Mode(final CustomMappingField... customFields) { this(customFields, (MappingField[]) null); } private Mode(final CustomMappingField[] customFields, final MappingField... excludedFields) { this.customFields = customFields; this.excludedFields = excludedFields; } /** * {@inheritDoc} */ @Override public String getMapId() { return name(); } /** * {@inheritDoc} */ @Override public CustomMappingField[] getCustomFields() { return customFields; } /** * {@inheritDoc} */ @Override public MappingField[] getExcludedFields() { return excludedFields; } } /** * Localizes an flexible element in the project model. * * @author tmi (v1.3) */ public static class LocalizedElement<E extends FlexibleElementDTO> { private final PhaseModelDTO phaseModel; private final E element; protected LocalizedElement(PhaseModelDTO phaseModel, E element) { this.phaseModel = phaseModel; this.element = element; } /** * Gets the flexible element. * * @return The flexible element. */ public E getElement() { return element; } /** * Get the phase model in which the element is displayed, or <code>null</code> if the element is in the details * page. * * @return The phase model of the element or <code>null</code>. */ public PhaseModelDTO getPhaseModel() { return phaseModel; } } private transient HashMap<Class<? extends FlexibleElementDTO>, List> localizedElements; private transient List<FlexibleElementDTO> allElements; public ProjectModelDTO() { // Serialization. } /** * Initializes a new project model with the given {@code status}. * * @param status * The project model status. */ public ProjectModelDTO(final ProjectModelStatus status) { setStatus(status); } /** * {@inheritDoc} */ @Override public String getEntityName() { return ENTITY_NAME; } /** * {@inheritDoc} */ @Override public ModelType getModelType() { return ModelType.ProjectModel; } /** * {@inheritDoc} */ @Override public List<AbstractModelDataEntityDTO<?>> getHasLayoutElements() { final List<AbstractModelDataEntityDTO<?>> hasLayoutElements = new ArrayList<AbstractModelDataEntityDTO<?>>(); hasLayoutElements.add(getProjectDetails()); if (getPhaseModels() != null) { for (final PhaseModelDTO phaseModel : getPhaseModels()) { hasLayoutElements.add(phaseModel); } } return hasLayoutElements; } /** * {@inheritDoc} */ @Override protected void appendToString(ToStringBuilder builder) { builder.append(NAME, getName()); builder.append(STATUS, getStatus()); } // --------------------------------------------------------------------------------------------- // // GETTERS & SETTERS. // // --------------------------------------------------------------------------------------------- // Project model name. /** * {@inheritDoc} */ @Override public String getName() { return get(NAME); } public void setName(String name) { set(NAME, name); } // Root phase model DTO. public PhaseModelDTO getRootPhaseModel() { return get(ROOT_PHASE_MODEL); } public void setRootPhaseModel(PhaseModelDTO rootPhaseModel) { set(ROOT_PHASE_MODEL, rootPhaseModel); } // Phase models list. public List<PhaseModelDTO> getPhaseModels() { return get(PHASE_MODELS); } public void setPhaseModels(List<PhaseModelDTO> phaseModels) { set(PHASE_MODELS, phaseModels); } // Reference to the project banner. public ProjectBannerDTO getProjectBanner() { return get(PROJECT_BANNER); } public void setProjectBanner(ProjectBannerDTO projectBanner) { set(PROJECT_BANNER, projectBanner); } // Reference to the project details. public ProjectDetailsDTO getProjectDetails() { return get(PROJECT_DETAILS); } public void setProjectDetails(ProjectDetailsDTO projectDetails) { set(PROJECT_DETAILS, projectDetails); } // Project visibilities. public List<ProjectModelVisibilityDTO> getVisibilities() { return get(VISIBILITIES); } public void setVisibilities(List<ProjectModelVisibilityDTO> visibilities) { set(VISIBILITIES, visibilities); } // LogFrame. public LogFrameModelDTO getLogFrameModel() { return get(LOG_FRAME_MODEL); } public void setLogFrameModel(LogFrameModelDTO logFrameModel) { set(LOG_FRAME_MODEL, logFrameModel); } // Status. /** * {@inheritDoc} */ @Override public ProjectModelStatus getStatus() { return get(STATUS); } public void setStatus(ProjectModelStatus status) { set(STATUS, status); } // Maintenance. /** * {@inheritDoc} */ @Override public boolean isUnderMaintenance() { return get(UNDER_MAINTENANCE); } public void setUnderMaintenance(boolean underMaintenance) { set(UNDER_MAINTENANCE, underMaintenance); } /** * {@inheritDoc} */ @Override public boolean isEditable() { return getStatus().isEditable() || isUnderMaintenance(); } // Maintenance start date. @Override public Date getDateMaintenance() { return get(MAINTENANCE_DATE); } public void setDateMaintenance(Date date) { set(MAINTENANCE_DATE, date); } // --------------------------------------------------------------------------------------------- // // UTILITY METHODS. // // --------------------------------------------------------------------------------------------- /** * Gets the type of this model for the given organization. If this model isn't visible for this organization, * <code>null</code> is returned. * * @param organizationId * The organization. * @return The type of this model for the given organization, <code>null</code> otherwise. */ public ProjectModelType getVisibility(int organizationId) { if (getVisibilities() == null) { return null; } for (final ProjectModelVisibilityDTO visibility : getVisibilities()) { if (visibility.getOrganizationId().equals(organizationId)) { return visibility.getType(); } } return null; } public List<ProfileDTO> getDefaultTeamMemberProfiles() { return get(DEFAULT_TEAM_MEMBER_PROFILES); } public void setDefaultTeamMemberProfiles(List<ProfileDTO> profiles) { set(DEFAULT_TEAM_MEMBER_PROFILES, profiles); } /** * Returns the current project model corresponding global export elements.<br> * Only the following types of elements are returned: * <ul> * <li>{@link ElementTypeEnum#DEFAULT}</li> * <li>{@link ElementTypeEnum#CHECKBOX}</li> * <li>{@link ElementTypeEnum#TEXT_AREA}</li> * <li>{@link ElementTypeEnum#TRIPLETS}</li> * <li>{@link ElementTypeEnum#QUESTION}</li> * </ul> * * @return The current project model corresponding global export elements. */ public List<FlexibleElementDTO> getGlobalExportElements() { final List<FlexibleElementDTO> allElements = new ArrayList<FlexibleElementDTO>(); // add phase groups for (final PhaseModelDTO phaseDTO : getPhaseModels()) { for (final LayoutGroupDTO lg : phaseDTO.getLayout().getGroups()) { for (final LayoutConstraintDTO lc : lg.getConstraints()) { final FlexibleElementDTO element = lc.getFlexibleElementDTO(); element.setGroup(lg); element.setConstraint(lc); element.setContainerModel(phaseDTO); final ElementTypeEnum type = element.getElementType(); if (ElementTypeEnum.DEFAULT == type || ElementTypeEnum.CHECKBOX == type || ElementTypeEnum.TEXT_AREA == type || ElementTypeEnum.TRIPLETS == type || ElementTypeEnum.QUESTION == type || ElementTypeEnum.CONTACT_LIST == type) { allElements.add(element); } } } } // add details groups final ProjectDetailsDTO p = getProjectDetails(); p.setName(); setProjectDetails(p); if (getProjectDetails().getLayout() != null) { for (final LayoutGroupDTO lg : getProjectDetails().getLayout().getGroups()) { for (final LayoutConstraintDTO lc : lg.getConstraints()) { final FlexibleElementDTO element = lc.getFlexibleElementDTO(); element.setGroup(lg); element.setConstraint(lc); element.setContainerModel(getProjectDetails()); final ElementTypeEnum type = element.getElementType(); if (ElementTypeEnum.DEFAULT == type || ElementTypeEnum.CHECKBOX == type || ElementTypeEnum.TEXT_AREA == type || ElementTypeEnum.TRIPLETS == type || ElementTypeEnum.QUESTION == type || ElementTypeEnum.CONTACT_LIST == type) { allElements.add(element); } } } } return allElements; } /** * {@inheritDoc} */ @Override public List<FlexibleElementDTO> getAllElements() { if (this.allElements != null) { return this.allElements; } final List<FlexibleElementDTO> allElements = new ArrayList<FlexibleElementDTO>(); final List<FlexibleElementDTO> bannerElements = new ArrayList<FlexibleElementDTO>(); // -- // Banner. // -- if (this.getProjectBanner().getLayout() != null) { for (final LayoutGroupDTO lg : getProjectBanner().getLayout().getGroups()) { for (final LayoutConstraintDTO lc : lg.getConstraints()) { final FlexibleElementDTO f = lc.getFlexibleElementDTO(); f.setBannerConstraint(lc); bannerElements.add(f); } } } // -- // Phases. // -- for (final PhaseModelDTO phaseModel : getPhaseModels()) { if (phaseModel != null) { final LayoutDTO layout = phaseModel.getLayout(); if (layout != null) { for (final LayoutGroupDTO lg : layout.getGroups()) { for (final LayoutConstraintDTO lc : lg.getConstraints()) { final FlexibleElementDTO f = lc.getFlexibleElementDTO(); f.setGroup(lg); f.setConstraint(lc); f.setContainerModel(phaseModel); for (final FlexibleElementDTO bf : bannerElements) { if (f.getId().equals(bf.getId())) { f.setBannerConstraint(bf.getBannerConstraint()); } } allElements.add(f); } } } } } // -- // Project Details. // -- final ProjectDetailsDTO p = getProjectDetails(); p.setName(); setProjectDetails(p); if (getProjectDetails().getLayout() != null) { for (final LayoutGroupDTO lg : getProjectDetails().getLayout().getGroups()) { for (final LayoutConstraintDTO lc : lg.getConstraints()) { final FlexibleElementDTO f = lc.getFlexibleElementDTO(); f.setGroup(lg); f.setConstraint(lc); f.setContainerModel(getProjectDetails()); for (final FlexibleElementDTO bf : bannerElements) { if (f.getId().equals(bf.getId())) { f.setBannerConstraint(bf.getBannerConstraint()); } } allElements.add(f); } } } this.allElements = allElements; return allElements; } /** * Gets all the flexible elements instances of the given class in this model (phases and details page). The banner is * ignored cause the elements in it are read-only. * * @param clazz * The class of the searched flexible elements. * @return The elements localized for the given class, or <code>null</code> if there is no element of this class. */ public <E extends FlexibleElementDTO> List<LocalizedElement<E>> getLocalizedElements(Class<E> clazz) { if (localizedElements != null) { return localizedElements.get(clazz); } localizedElements = new HashMap<Class<? extends FlexibleElementDTO>, List>(); // Details. for (final LayoutGroupDTO group : getProjectDetails().getLayout().getGroups()) { // For each constraint. for (final LayoutConstraintDTO constraint : group.getConstraints()) { // Gets the element and its class. final FlexibleElementDTO element = constraint.getFlexibleElementDTO(); List elements = localizedElements.get(element.getClass()); // First element for this class. if (elements == null) { elements = new ArrayList<LocalizedElement<?>>(); localizedElements.put(element.getClass(), elements); } // Maps the element. elements.add(new LocalizedElement(null, element)); } } // For each phase. for (final PhaseModelDTO phaseModel : getPhaseModels()) { // For each group. for (final LayoutGroupDTO group : phaseModel.getLayout().getGroups()) { // For each constraint. for (final LayoutConstraintDTO constraint : group.getConstraints()) { // Gets the element and its class. final FlexibleElementDTO element = constraint.getFlexibleElementDTO(); List<LocalizedElement> elements = localizedElements.get(element.getClass()); // First element for this class. if (elements == null) { elements = new ArrayList<LocalizedElement>(); localizedElements.put(element.getClass(), elements); } // Maps the element. elements.add(new LocalizedElement(phaseModel, element)); } } } return localizedElements.get(clazz); } }