001/*
002 *  Copyright 2025 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;
017
018import java.util.HashMap;
019import java.util.List;
020import java.util.Map;
021
022import org.apache.avalon.framework.configuration.Configuration;
023import org.apache.avalon.framework.configuration.ConfigurationException;
024import org.apache.avalon.framework.context.Context;
025import org.apache.avalon.framework.context.ContextException;
026import org.apache.cocoon.components.ContextHelper;
027import org.apache.cocoon.environment.Request;
028import org.apache.ibatis.mapping.Environment;
029import org.apache.ibatis.session.SqlSession;
030import org.apache.ibatis.type.JdbcType;
031import org.apache.ibatis.type.TypeHandlerRegistry;
032
033import org.ametys.core.datasource.AbstractMyBatisDAO;
034import org.ametys.core.datasource.ZonedDateTimeTypeHandler;
035import org.ametys.plugins.odfsync.apogee.scc.AbstractApogeeSynchronizableContentsCollection;
036
037/**
038 * Data access object to the remote DB Apogee
039 */
040public abstract class AbstractApogeeDAO extends AbstractMyBatisDAO
041{
042    /** The name of request attribute for the datasource id */
043    protected static final String DATASOURCE_REQUEST_ATTR = AbstractApogeeDAO.class.getName() + "$dataSourceId";
044    
045    private Context _context;
046    
047    @Override
048    public void contextualize(Context context) throws ContextException
049    {
050        super.contextualize(context);
051        _context = context;
052    }
053
054    @Override
055    protected org.apache.ibatis.session.Configuration _getMyBatisConfiguration(Environment env)
056    {
057        org.apache.ibatis.session.Configuration config = super._getMyBatisConfiguration(env);
058        TypeHandlerRegistry typeHandlerRegistry = config.getTypeHandlerRegistry();
059        
060        // Transform date types to ZonedDateTime
061        typeHandlerRegistry.register(Object.class, JdbcType.DATE, ZonedDateTimeTypeHandler.class);
062        typeHandlerRegistry.register(Object.class, JdbcType.TIMESTAMP, ZonedDateTimeTypeHandler.class);
063        
064        return config;
065    }
066    
067    @Override
068    protected void _configureDatasource(Configuration configuration) throws ConfigurationException
069    {
070        // Do nothing
071    }
072    
073    @Override
074    protected String _getDataSourceId()
075    {
076        // Get data source id from request attributes
077        return (String) _getRequest().getAttribute(DATASOURCE_REQUEST_ATTR);
078    }
079    
080    /**
081     * Get the request
082     * @return the request
083     */
084    protected Request _getRequest()
085    {
086        Request request = ContextHelper.getRequest(_context);
087        if (request == null)
088        {
089            throw new IllegalStateException("Apogee DAO can not be used outside a request");
090        }
091        return request;
092    }
093    
094    /**
095     * Returns the Apogee objects matching the search criteria on the asked statement.
096     * @param dataSourceId The id of data source. Can not be null.
097     * @param sccParams the parameters values of the Apogee synchronizable collection
098     * @param params The parameters for search criteria
099     * @param query The query identifier to execute
100     * @return the list Apogee objects matching the search criteria
101     */
102    protected List<Map<String, Object>> _executeSearch(String dataSourceId, Map<String, Object> sccParams, Map<String, Object> params, String query)
103    {
104        Map<String, Object> sqlParams = new HashMap<>(params);
105        _prepareSqlRequest(dataSourceId, sccParams, sqlParams);
106        
107        try (SqlSession session = getSession())
108        {
109            return session.selectList(query, sqlParams);
110        }
111    }
112    
113    /**
114     * Common method to prepare the SQL request to execute
115     * @param dataSourceId The id of data source. Can not be null.
116     * @param sccParams the parameters values of the used Apogee synchronizable collection
117     * @param params the SQL parameters
118     */
119    protected void _prepareSqlRequest(String dataSourceId, Map<String, Object> sccParams, Map<String, Object> params)
120    {
121        // Set data source id in request attributes
122        _getRequest().setAttribute(DATASOURCE_REQUEST_ATTR, dataSourceId);
123        
124        // Add administrative year to SQL parameters if exists
125        if (sccParams.containsKey(AbstractApogeeSynchronizableContentsCollection.PARAM_YEAR))
126        {
127            params.put("year", sccParams.get(AbstractApogeeSynchronizableContentsCollection.PARAM_YEAR));
128        }
129    }
130}