/** * Licensed to Apereo under one or more contributor license agreements. See the NOTICE file * distributed with this work for additional information regarding copyright ownership. Apereo * licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use * this file except in compliance with the License. You may obtain a copy of the License at the * following location: * * <p>http://www.apache.org/licenses/LICENSE-2.0 * * <p>Unless required by applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ package org.apereo.portal.io.xml.eventaggr; import com.google.common.base.Function; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import org.apereo.portal.events.aggr.AcademicTermDetail; import org.apereo.portal.events.aggr.AggregatedGroupConfig; import org.apereo.portal.events.aggr.AggregatedIntervalConfig; import org.apereo.portal.events.aggr.AggregationInterval; import org.apereo.portal.events.aggr.EventDateTimeUtils; import org.apereo.portal.events.aggr.IPortalEventAggregator; import org.apereo.portal.events.aggr.QuarterDetail; import org.apereo.portal.events.aggr.dao.IEventAggregationManagementDao; import org.apereo.portal.events.aggr.dao.jpa.AcademicTermDetailImpl; import org.apereo.portal.events.aggr.dao.jpa.QuarterDetailImpl; import org.apereo.portal.events.aggr.groups.AggregatedGroupLookupDao; import org.apereo.portal.events.aggr.groups.AggregatedGroupMapping; import org.apereo.portal.io.xml.AbstractJaxbDataHandler; import org.apereo.portal.io.xml.IPortalData; import org.apereo.portal.io.xml.IPortalDataType; import org.apereo.portal.io.xml.PortalDataKey; import org.apereo.portal.utils.EnumNameComparator; import org.apereo.portal.utils.SafeFilenameUtils; import org.joda.time.DateMidnight; import org.joda.time.MonthDay; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; public class EventAggregationConfigurationImporterExporter extends AbstractJaxbDataHandler<ExternalEventAggregationConfiguration> { private static final String SINGLE_DATA_ID = "CONFIG"; private EventAggregationConfigurationPortalDataType eventAggregationDataType; private IEventAggregationManagementDao aggregationManagementDao; private AggregatedGroupLookupDao aggregatedGroupLookupDao; @Autowired public void setAggregatedGroupLookupDao(AggregatedGroupLookupDao aggregatedGroupLookupDao) { this.aggregatedGroupLookupDao = aggregatedGroupLookupDao; } @Autowired public void setEventAggregationDataType( EventAggregationConfigurationPortalDataType eventAggregationDataType) { this.eventAggregationDataType = eventAggregationDataType; } @Autowired public void setAggregationManagementDao( IEventAggregationManagementDao aggregationManagementDao) { this.aggregationManagementDao = aggregationManagementDao; } @Override public Set<PortalDataKey> getImportDataKeys() { return Collections.singleton( EventAggregationConfigurationPortalDataType.IMPORT_40_DATA_KEY); } @Override public IPortalDataType getPortalDataType() { return this.eventAggregationDataType; } @Override public Iterable<? extends IPortalData> getPortalData() { return ImmutableSet.of( new IPortalData() { @Override public String getDataId() { return "Event Aggregation Configuration"; } @Override public String getDataTitle() { return SINGLE_DATA_ID; } @Override public String getDataDescription() { return null; } }); } @Transactional("aggrEventsTransactionManager") @Override public void importData(ExternalEventAggregationConfiguration data) { //Import interval configs final Set<AggregatedIntervalConfig> oldAggregatedIntervalConfigs = new HashSet<AggregatedIntervalConfig>( this.aggregationManagementDao.getAggregatedIntervalConfigs()); for (final ExternalAggregatedIntervalConfig extAggregatedIntervalConfig : data.getAggregatedIntervalConfigs()) { final String aggregatorTypeName = extAggregatedIntervalConfig.getAggregatorType(); final Class<? extends IPortalEventAggregator> aggregatorType = getAggregatorType(aggregatorTypeName); AggregatedIntervalConfig aggregatedIntervalConfig = this.aggregationManagementDao.getAggregatedIntervalConfig(aggregatorType); if (aggregatedIntervalConfig == null) { aggregatedIntervalConfig = this.aggregationManagementDao.createAggregatedIntervalConfig( aggregatorType); } //Remove the config from the old configs set, marking it as updated oldAggregatedIntervalConfigs.remove(aggregatedIntervalConfig); //Copy over excludes final Set<AggregationInterval> excluded = aggregatedIntervalConfig.getExcluded(); excluded.clear(); for (final ExternalAggregationInterval extInterval : extAggregatedIntervalConfig.getExcludes()) { excluded.add(convert(extInterval)); } //Copy over includes final Set<AggregationInterval> included = aggregatedIntervalConfig.getIncluded(); included.clear(); for (final ExternalAggregationInterval extInterval : extAggregatedIntervalConfig.getIncludes()) { included.add(convert(extInterval)); } this.aggregationManagementDao.updateAggregatedIntervalConfig(aggregatedIntervalConfig); } //Delete interval configs that were not updated for (final AggregatedIntervalConfig aggregatedIntervalConfig : oldAggregatedIntervalConfigs) { this.aggregationManagementDao.deleteAggregatedIntervalConfig(aggregatedIntervalConfig); } //Import Group configs final Set<AggregatedGroupConfig> oldAggregatedGroupConfigs = new HashSet<AggregatedGroupConfig>( this.aggregationManagementDao.getAggregatedGroupConfigs()); for (final ExternalAggregatedGroupConfig extAggregatedGroupConfig : data.getAggregatedGroupConfigs()) { final String aggregatorTypeName = extAggregatedGroupConfig.getAggregatorType(); final Class<? extends IPortalEventAggregator> aggregatorType = getAggregatorType(aggregatorTypeName); AggregatedGroupConfig aggregatedGroupConfig = this.aggregationManagementDao.getAggregatedGroupConfig(aggregatorType); if (aggregatedGroupConfig == null) { aggregatedGroupConfig = this.aggregationManagementDao.createAggregatedGroupConfig(aggregatorType); } //Remove the config from the old configs set, marking it as updated oldAggregatedGroupConfigs.remove(aggregatedGroupConfig); //Copy over excludes final Set<AggregatedGroupMapping> excluded = aggregatedGroupConfig.getExcluded(); excluded.clear(); for (final ExternalAggregatedGroupMapping extGroup : extAggregatedGroupConfig.getExcludes()) { excluded.add(convert(extGroup)); } //Copy over includes final Set<AggregatedGroupMapping> included = aggregatedGroupConfig.getIncluded(); included.clear(); for (final ExternalAggregatedGroupMapping extGroup : extAggregatedGroupConfig.getIncludes()) { included.add(convert(extGroup)); } this.aggregationManagementDao.updateAggregatedGroupConfig(aggregatedGroupConfig); } //Delete interval configs that were not updated for (final AggregatedGroupConfig aggregatedGroupConfig : oldAggregatedGroupConfigs) { this.aggregationManagementDao.deleteAggregatedGroupConfig(aggregatedGroupConfig); } //Set quarter details if configured or set default quarters final List<ExternalQuarterDetail> extQuarterDetails = data.getQuarterDetails(); final List<QuarterDetail> quarterDetails; if (!extQuarterDetails.isEmpty()) { quarterDetails = convertQuarterDetail(extQuarterDetails); } else { quarterDetails = EventDateTimeUtils.createStandardQuarters(); } this.aggregationManagementDao.setQuarterDetails(quarterDetails); //Set academic term if configured final List<AcademicTermDetail> academicTerms = Lists.transform( data.getTermDetails(), new Function<ExternalTermDetail, AcademicTermDetail>() { public AcademicTermDetail apply(ExternalTermDetail externalTermDetail) { return new AcademicTermDetailImpl( new DateMidnight(externalTermDetail.getStart()), new DateMidnight(externalTermDetail.getEnd()), externalTermDetail.getName()); } }); this.aggregationManagementDao.setAcademicTermDetails(academicTerms); } protected List<QuarterDetail> convertQuarterDetail( List<ExternalQuarterDetail> externalQuarterDetails) { final List<QuarterDetail> quarterDetails = new ArrayList<QuarterDetail>(4); for (final ExternalQuarterDetail externalQuarterDetail : externalQuarterDetails) { quarterDetails.add( new QuarterDetailImpl( MonthDay.parse(externalQuarterDetail.getStart()), MonthDay.parse(externalQuarterDetail.getEnd()), externalQuarterDetail.getId())); } return quarterDetails; } protected AggregatedGroupMapping convert( ExternalAggregatedGroupMapping externalAggregatedGroupMapping) { return this.aggregatedGroupLookupDao.getGroupMapping( externalAggregatedGroupMapping.getGroupService(), externalAggregatedGroupMapping.getGroupName()); } protected AggregationInterval convert(ExternalAggregationInterval externalAggregationInterval) { return AggregationInterval.valueOf(externalAggregationInterval.name()); } protected Class<? extends IPortalEventAggregator> getAggregatorType(String aggregatorTypeName) { /* * For version 5.0, all uPortal sources were repackaged from 'org.jasig.portal' * to 'org.apereo.portal'. *.event-aggregation.xml files exported from earlier * versions of uPortal will contain the old package name. We can detect that * and intervene here. */ aggregatorTypeName = aggregatorTypeName.replace("org.jasig.portal", "org.apereo.portal"); final Class<?> aggregatorType; try { aggregatorType = Class.forName(aggregatorTypeName); } catch (ClassNotFoundException e) { throw new RuntimeException( "Specified aggregator type name " + aggregatorTypeName + " could not be resolved to a Class", e); } if (!IPortalEventAggregator.class.isAssignableFrom(aggregatorType)) { throw new IllegalArgumentException( "Specified aggregator type " + aggregatorType.getName() + " is not an instance of " + IPortalEventAggregator.class.getName()); } return (Class<? extends IPortalEventAggregator>) aggregatorType; } /* * (non-Javadoc) * @see org.apereo.portal.io.xml.IDataImporterExporter#exportData(java.lang.String) */ @Override public ExternalEventAggregationConfiguration exportData(String id) { final ExternalEventAggregationConfiguration externalData = new ExternalEventAggregationConfiguration(); //Copy interval configs final List<ExternalAggregatedIntervalConfig> aggregatedIntervalConfigs = externalData.getAggregatedIntervalConfigs(); for (final AggregatedIntervalConfig aggregatedIntervalConfig : this.aggregationManagementDao.getAggregatedIntervalConfigs()) { final ExternalAggregatedIntervalConfig externalIntervalConfig = new ExternalAggregatedIntervalConfig(); externalIntervalConfig.setAggregatorType( aggregatedIntervalConfig.getAggregatorType().getName()); final List<ExternalAggregationInterval> extIncludes = externalIntervalConfig.getIncludes(); for (final AggregationInterval interval : aggregatedIntervalConfig.getIncluded()) { extIncludes.add(convert(interval)); } Collections.sort(extIncludes, EnumNameComparator.INSTANCE); final List<ExternalAggregationInterval> extExcludes = externalIntervalConfig.getExcludes(); for (final AggregationInterval interval : aggregatedIntervalConfig.getExcluded()) { extExcludes.add(convert(interval)); } Collections.sort(extExcludes, EnumNameComparator.INSTANCE); aggregatedIntervalConfigs.add(externalIntervalConfig); } Collections.sort( aggregatedIntervalConfigs, ExternalAggregatedDimensionConfigComparator.INSTANCE); //Copy group configs final List<ExternalAggregatedGroupConfig> aggregatedGroupConfigs = externalData.getAggregatedGroupConfigs(); for (final AggregatedGroupConfig aggregatedGroupConfig : this.aggregationManagementDao.getAggregatedGroupConfigs()) { final ExternalAggregatedGroupConfig externalGroupConfig = new ExternalAggregatedGroupConfig(); externalGroupConfig.setAggregatorType( aggregatedGroupConfig.getAggregatorType().getName()); final List<ExternalAggregatedGroupMapping> extIncludes = externalGroupConfig.getIncludes(); for (final AggregatedGroupMapping Group : aggregatedGroupConfig.getIncluded()) { extIncludes.add(convert(Group)); } Collections.sort(extIncludes, ExternalAggregatedGroupMappingComparator.INSTANCE); final List<ExternalAggregatedGroupMapping> extExcludes = externalGroupConfig.getExcludes(); for (final AggregatedGroupMapping Group : aggregatedGroupConfig.getExcluded()) { extExcludes.add(convert(Group)); } Collections.sort(extExcludes, ExternalAggregatedGroupMappingComparator.INSTANCE); aggregatedGroupConfigs.add(externalGroupConfig); } Collections.sort( aggregatedGroupConfigs, ExternalAggregatedDimensionConfigComparator.INSTANCE); //Copy term details final List<ExternalTermDetail> externalTermDetails = externalData.getTermDetails(); for (final AcademicTermDetail academicTermDetail : this.aggregationManagementDao.getAcademicTermDetails()) { final ExternalTermDetail externalTermDetail = new ExternalTermDetail(); externalTermDetail.setName(academicTermDetail.getTermName()); externalTermDetail.setStart(academicTermDetail.getStart().toGregorianCalendar()); externalTermDetail.setEnd(academicTermDetail.getEnd().toGregorianCalendar()); externalTermDetails.add(externalTermDetail); } Collections.sort(externalTermDetails, ExternalTermDetailComparator.INSTANCE); //Copy quarter details final List<ExternalQuarterDetail> quarterDetails = externalData.getQuarterDetails(); for (final QuarterDetail quarterDetail : this.aggregationManagementDao.getQuartersDetails()) { final ExternalQuarterDetail externalQuarterDetail = new ExternalQuarterDetail(); externalQuarterDetail.setId(quarterDetail.getQuarterId()); externalQuarterDetail.setStart(quarterDetail.getStart().toString()); externalQuarterDetail.setEnd(quarterDetail.getEnd().toString()); quarterDetails.add(externalQuarterDetail); } Collections.sort(quarterDetails, ExternalQuarterDetailComparator.INSTANCE); return externalData; } protected ExternalAggregationInterval convert(AggregationInterval aggregationInterval) { return ExternalAggregationInterval.valueOf(aggregationInterval.name()); } protected ExternalAggregatedGroupMapping convert( AggregatedGroupMapping aggregatedGroupMapping) { final ExternalAggregatedGroupMapping externalAggregatedGroupMapping = new ExternalAggregatedGroupMapping(); externalAggregatedGroupMapping.setGroupService(aggregatedGroupMapping.getGroupService()); externalAggregatedGroupMapping.setGroupName(aggregatedGroupMapping.getGroupName()); return externalAggregatedGroupMapping; } @Override public String getFileName(ExternalEventAggregationConfiguration data) { return SafeFilenameUtils.makeSafeFilename("default"); } /* * (non-Javadoc) * @see org.apereo.portal.io.xml.IDataImporterExporter#deleteData(java.lang.String) */ @Transactional("aggrEventsTransactionManager") @Override public ExternalEventAggregationConfiguration deleteData(String id) { final ExternalEventAggregationConfiguration data = this.exportData(id); for (final AggregatedIntervalConfig aggregatedIntervalConfig : this.aggregationManagementDao.getAggregatedIntervalConfigs()) { this.aggregationManagementDao.deleteAggregatedIntervalConfig(aggregatedIntervalConfig); } for (final AggregatedGroupConfig aggregatedGroupConfig : this.aggregationManagementDao.getAggregatedGroupConfigs()) { this.aggregationManagementDao.deleteAggregatedGroupConfig(aggregatedGroupConfig); } this.aggregationManagementDao.setAcademicTermDetails( Collections.<AcademicTermDetail>emptyList()); this.aggregationManagementDao.setQuarterDetails( EventDateTimeUtils.createStandardQuarters()); return data; } }