001/*
002 *  Copyright 2019 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.plugins.odfsync.apogee.ws;
017
018import java.util.HashMap;
019import java.util.Map;
020import java.util.Set;
021import java.util.stream.Collectors;
022
023import org.apache.avalon.framework.component.Component;
024import org.apache.avalon.framework.service.ServiceException;
025import org.apache.avalon.framework.service.ServiceManager;
026import org.apache.avalon.framework.service.Serviceable;
027
028import org.ametys.cms.contenttype.ContentType;
029import org.ametys.cms.contenttype.ContentTypeExtensionPoint;
030import org.ametys.cms.repository.Content;
031import org.ametys.core.ui.Callable;
032import org.ametys.core.util.I18nUtils;
033import org.ametys.odf.ProgramItem;
034import org.ametys.odf.course.Course;
035import org.ametys.odf.courselist.CourseList;
036import org.ametys.odf.orgunit.OrgUnit;
037import org.ametys.odf.program.Container;
038import org.ametys.odf.program.Program;
039import org.ametys.odf.program.SubProgram;
040import org.ametys.plugins.odfsync.apogee.ws.ApogeeExportReport.ExportStatus;
041import org.ametys.plugins.odfsync.apogee.ws.structure.AbstractApogeeStructure;
042import org.ametys.plugins.odfsync.apogee.ws.structure.ApogeeExportStructure;
043import org.ametys.plugins.repository.AmetysObjectResolver;
044import org.ametys.runtime.i18n.I18nizableText;
045import org.ametys.runtime.model.ModelItem;
046
047/**
048 * Component for Apogee export
049 */
050public class ApogeeStructureComponent implements Serviceable, Component
051{
052    /** Avalon Role */
053    public static final String ROLE = ApogeeStructureComponent.class.getName();
054    
055    /** The apogee export extension point */
056    protected ApogeeExportExtensionPoint _exportApogeeEP;
057    
058    /** The Ametys object resolver */
059    protected AmetysObjectResolver _resolver;
060    
061    /** The i18nUtils */
062    protected I18nUtils _i18nUtils;
063    
064    /** The content type extension point */
065    protected ContentTypeExtensionPoint _ctExtPoint;
066    
067    @Override
068    public void service(ServiceManager manager) throws ServiceException
069    {
070        _exportApogeeEP = (ApogeeExportExtensionPoint) manager.lookup(ApogeeExportExtensionPoint.ROLE);
071        _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE);
072        _i18nUtils = (I18nUtils) manager.lookup(I18nUtils.ROLE);
073        _ctExtPoint = (ContentTypeExtensionPoint) manager.lookup(ContentTypeExtensionPoint.ROLE);
074    }
075    
076    /**
077     * Get the Apogee export report of the program id
078     * @param programId the program id
079     * @return the Apogee export report
080     */
081    public ApogeeExportReport getApogeeExportReport(String programId)
082    {
083        Program program = _resolver.resolveById(programId);
084
085        for (String implementationId : _exportApogeeEP.getExtensionsIds())
086        {
087            ApogeeExportStructure exportApogeeStructure = _exportApogeeEP.getExtension(implementationId);
088            
089            ApogeeExportReport report = new ApogeeExportReport(ExportStatus.OK);
090            exportApogeeStructure.checkProgram(program, report);
091
092            ExportStatus exportStatus = report.getExportStatus();
093            
094            // Check if the structure is good
095            // Do nothing  if the structure is invalid and continue to check the other Apogee implementations
096            if (exportStatus != ExportStatus.CONTENT_STRUCTURE_INVALID)
097            {
098                report.setApogeeExportStructure(exportApogeeStructure);
099                return report;
100            }
101        }
102        
103        // No implementation for this program structure 
104        return new ApogeeExportReport(ExportStatus.CONTENT_STRUCTURE_INVALID);
105    }
106    
107    /**
108     * Get the report informations of the Apogee export of the program id
109     * @param programId the program id to export
110     * @return the export results
111     */
112    @Callable
113    public Map<String, Object> getApogeeExportReportInfo(String programId)
114    {
115        ApogeeExportReport report = getApogeeExportReport(programId);
116        ExportStatus exportStatus = report.getExportStatus();
117        
118        Map<String, Object> results = new HashMap<>();
119        results.put("status", exportStatus.name());
120        if (exportStatus == ExportStatus.CONTENT_DATA_INVALID)
121        {
122            Map<String, Object> programReport = new HashMap<>();
123            Map<String, Object> subProgramReport = new HashMap<>();
124            Map<String, Object> containerYearReport = new HashMap<>();
125            Map<String, Object> containerSemesterReport = new HashMap<>();
126            Map<String, Object> courseListReport = new HashMap<>();
127            Map<String, Object> courseReport = new HashMap<>();
128            Map<String, Object> orgUnitReport = new HashMap<>();
129            Map<String, Object> otherContentReport = new HashMap<>();
130            
131            Map<Content, Set<ModelItem>> mandatoryDataByContent = report.getMandatoryDataPathByContent();
132            for (Content content : mandatoryDataByContent.keySet())
133            {
134                if (content instanceof Program)
135                {
136                    programReport.put(content.getId(), _getParams(content, mandatoryDataByContent.get(content)));
137                }
138                else if (content instanceof SubProgram)
139                {
140                    subProgramReport.put(content.getId(), _getParams(content, mandatoryDataByContent.get(content)));
141                }
142                else if (content instanceof Container)
143                {
144                    if (((AbstractApogeeStructure) report.getApogeeExportStructure()).isYearContainer((Container) content, report))
145                    {
146                        containerYearReport.put(content.getId(), _getParams(content, mandatoryDataByContent.get(content)));
147                    }
148                    else
149                    {
150                        containerSemesterReport.put(content.getId(), _getParams(content, mandatoryDataByContent.get(content)));
151                    }
152                }
153                else if (content instanceof CourseList)
154                {
155                    courseListReport.put(content.getId(), _getParams(content, mandatoryDataByContent.get(content)));
156                }
157                else if (content instanceof Course)
158                {
159                    courseReport.put(content.getId(), _getParams(content, mandatoryDataByContent.get(content)));
160                }
161                else if (content instanceof OrgUnit)
162                {
163                    orgUnitReport.put(content.getId(), _getParams(content, mandatoryDataByContent.get(content)));
164                }
165                else
166                {
167                    otherContentReport.put(content.getId(), _getParams(content, mandatoryDataByContent.get(content)));
168                }
169            }
170            
171            results.put("program", programReport);
172            results.put("subprogram", subProgramReport);
173            results.put("container-year", containerYearReport);
174            results.put("container-semester", containerSemesterReport);
175            results.put("courselist", courseListReport);
176            results.put("course", courseReport);
177            results.put("orgunit", orgUnitReport);
178            results.put("other", otherContentReport);
179            
180            return results;
181        }
182        
183        return results;
184    }
185    
186    private Map<String, Object> _getParams(Content content, Set<ModelItem> modelItems)
187    {
188        Map<String, Object> params = new HashMap<>();
189        params.put("contentTitle", content.getTitle());
190        if (content instanceof ProgramItem)
191        {
192            params.put("contentCode", ((ProgramItem) content).getCode());
193        }
194        else if (content instanceof OrgUnit)
195        {
196            params.put("contentCode", ((OrgUnit) content).getCode());
197        }
198        else
199        {
200            String contentTypeId = content.getTypes()[0];
201            ContentType contentType = _ctExtPoint.getExtension(contentTypeId);
202            params.put("contentTypeLabel", contentType.getLabel());
203            params.put("contentTypeId", contentTypeId);
204            params.put("isTableRef", true);
205        }
206        
207        Set<I18nizableText> attributes = modelItems.stream()
208            .map(ModelItem::getLabel)
209            .collect(Collectors.toSet());
210        params.put("attributes", attributes);
211        
212        return params;
213    }
214}