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.odf.ose.export.impl;
017
018import java.sql.Types;
019import java.util.ArrayList;
020import java.util.Comparator;
021import java.util.HashSet;
022import java.util.List;
023import java.util.Set;
024import java.util.stream.Collectors;
025import java.util.stream.Stream;
026
027import org.apache.avalon.framework.service.ServiceException;
028import org.apache.avalon.framework.service.ServiceManager;
029import org.apache.avalon.framework.service.Serviceable;
030import org.apache.commons.lang3.StringUtils;
031import org.apache.commons.lang3.tuple.Pair;
032
033import org.ametys.cms.data.ContentValue;
034import org.ametys.odf.enumeration.OdfReferenceTableEntry;
035import org.ametys.odf.enumeration.OdfReferenceTableHelper;
036import org.ametys.odf.ose.db.ParameterizableQuery;
037import org.ametys.odf.ose.db.column.Column;
038import org.ametys.odf.ose.db.column.DefaultColumn;
039import org.ametys.odf.ose.db.column.ForeignKeyColumn;
040import org.ametys.odf.ose.db.column.SourceIdColumn;
041import org.ametys.odf.ose.db.parameter.QueryParameter;
042import org.ametys.odf.ose.db.parameter.ValuedQueryParameter;
043import org.ametys.odf.ose.export.AbstractOSEExport;
044import org.ametys.odf.ose.export.ExportUtils;
045import org.ametys.runtime.config.Config;
046
047/**
048 * This exports degrees to GROUPE_TYPE_FORMATION and TYPE_FORMATION tables.
049 */
050public class TypeFormationExport extends AbstractOSEExport implements Serviceable
051{
052    private static final String __GROUPE_TYPE_TABLE_NAME = "GROUPE_TYPE_FORMATION";
053    private static final String __TYPE_TABLE_NAME = "TYPE_FORMATION";
054    
055    private static final String __DEGREE_CATEGORY_CONTENT_TYPE = "odf-enumeration.DegreeCategory";
056    private static final String __DEGREES_ATTRIBUTE_NAME = "degrees";
057
058    /** The ODF enumeration helper */
059    protected OdfReferenceTableHelper _refTableHelper;
060    
061    @Override
062    public void service(ServiceManager manager) throws ServiceException
063    {
064        _refTableHelper = (OdfReferenceTableHelper) manager.lookup(OdfReferenceTableHelper.ROLE);
065    }
066    
067    @Override
068    public List<ParameterizableQuery> initializeDb()
069    {
070        List<ParameterizableQuery> queries = new ArrayList<>();
071
072        Set<Column> columns = new HashSet<>();
073        columns.add(new DefaultColumn("ID", "VARCHAR2(100 CHAR)", false, "SOURCE_CODE"));
074        columns.add(new DefaultColumn("LIBELLE_COURT", "VARCHAR2(20 CHAR)", false));
075        columns.add(new DefaultColumn("LIBELLE_LONG", "VARCHAR2(50 CHAR)", false));
076        columns.add(new DefaultColumn("ORDRE", "NUMBER(*,0)", false));
077        columns.add(new SourceIdColumn());
078        queries.addAll(ExportUtils.initializeTableAndView(__GROUPE_TYPE_TABLE_NAME, columns));
079        
080        columns = new HashSet<>();
081        columns.add(new DefaultColumn("ID", "VARCHAR2(100 CHAR)", false, "SOURCE_CODE"));
082        columns.add(new DefaultColumn("LIBELLE_LONG", "VARCHAR2(80 CHAR)", false));
083        columns.add(new DefaultColumn("LIBELLE_COURT", "VARCHAR2(15 CHAR)", false));
084        columns.add(new ForeignKeyColumn("GROUPE_ID", "VARCHAR2(100 CHAR)", false, Pair.of("GROUPE_TYPE_FORMATION", "SOURCE_CODE"), false));
085        columns.add(new SourceIdColumn());
086        queries.addAll(ExportUtils.initializeTableAndView(__TYPE_TABLE_NAME, columns));
087        
088        return queries;
089    }
090
091    @Override
092    public List<ParameterizableQuery> _populate(String ametysCatalog, Long oseCatalog)
093    {
094        List<ParameterizableQuery> queries = new ArrayList<>();
095
096        // Remove all values
097        queries.add(ExportUtils.deleteFromAmetys(__TYPE_TABLE_NAME));
098        queries.add(ExportUtils.deleteFromAmetys(__GROUPE_TYPE_TABLE_NAME));
099        
100        // Add all values
101        queries.addAll(_getInsertQueries());
102        
103        return queries;
104    }
105
106    private List<ParameterizableQuery> _getInsertQueries()
107    {
108        String lang = Config.getInstance().getValue("odf.programs.lang");
109        
110        return _refTableHelper.getItems(__DEGREE_CATEGORY_CONTENT_TYPE)
111            .stream()
112            .sorted(Comparator
113                    .comparingLong(OdfReferenceTableEntry::getOrder)
114                    .thenComparing(OdfReferenceTableEntry::getCode))
115            .flatMap(degreeCategory -> _getInsertQueries(degreeCategory, lang))
116            .collect(Collectors.toList());
117    }
118    
119    private Stream<ParameterizableQuery> _getInsertQueries(OdfReferenceTableEntry degreeCategory, String lang)
120    {
121        Stream.Builder<ParameterizableQuery> queries = Stream.builder();
122        
123        // Add the group of types (group of degrees)
124        queries.add(_getInsertQueryForGroupType(degreeCategory, lang));
125        
126        // Add the types (degrees)
127        String degreeCategoryCode = degreeCategory.getCode();
128        ContentValue[] degrees = degreeCategory.getContent().getValue(__DEGREES_ATTRIBUTE_NAME, false, new ContentValue[0]);
129        for (ContentValue degree : degrees)
130        {
131            degree.getContentIfExists()
132                .map(OdfReferenceTableEntry::new)
133                .map(entry -> _getInsertQueryForType(entry, lang, degreeCategoryCode))
134                .ifPresent(queries::add);
135        }
136
137        return queries.build();
138    }
139    
140    private ParameterizableQuery _getInsertQueryForGroupType(OdfReferenceTableEntry degreeCategory, String lang)
141    {
142        String code = degreeCategory.getCode();
143        String label = degreeCategory.getLabel(lang);
144        Long order = degreeCategory.getOrder();
145        
146        List<QueryParameter> parameters = new ArrayList<>();
147        parameters.add(new ValuedQueryParameter("ID", code, Types.VARCHAR));
148        parameters.add(new ValuedQueryParameter("LIBELLE_COURT", StringUtils.truncate(label, 20), Types.VARCHAR));
149        parameters.add(new ValuedQueryParameter("LIBELLE_LONG", StringUtils.truncate(label, 50), Types.VARCHAR));
150        parameters.add(new ValuedQueryParameter("ORDRE", order, Types.NUMERIC));
151        return ExportUtils.insertIntoAmetys(__GROUPE_TYPE_TABLE_NAME, parameters);
152    }
153    
154    private ParameterizableQuery _getInsertQueryForType(OdfReferenceTableEntry degree, String lang, String degreeCategoryCode)
155    {
156        String code = degree.getCode();
157        String label = degree.getLabel(lang);
158        
159        List<QueryParameter> parameters = new ArrayList<>();
160        parameters.add(new ValuedQueryParameter("ID", code, Types.VARCHAR));
161        parameters.add(new ValuedQueryParameter("LIBELLE_LONG", StringUtils.truncate(label, 80), Types.VARCHAR));
162        parameters.add(new ValuedQueryParameter("LIBELLE_COURT", StringUtils.truncate(label, 15), Types.VARCHAR));
163        parameters.add(new ValuedQueryParameter("GROUPE_ID", degreeCategoryCode, Types.VARCHAR));
164        return ExportUtils.insertIntoAmetys(__TYPE_TABLE_NAME, parameters);
165    }
166    
167}