/** {@link IDataUpgrader} implementations to delegate upgrade operations to. */ @Autowired(required = false) public void setDataUpgraders(Collection<IDataUpgrader> dataUpgraders) { final Map<PortalDataKey, IDataUpgrader> dataUpgraderMap = new LinkedHashMap<PortalDataKey, IDataUpgrader>(); for (final IDataUpgrader dataUpgrader : dataUpgraders) { try { final Set<PortalDataKey> upgradeDataKeys = dataUpgrader.getSourceDataTypes(); for (final PortalDataKey upgradeDataKey : upgradeDataKeys) { this.logger.debug( "Registering IDataUpgrader for '{}' - {}", upgradeDataKey, dataUpgrader); final IDataUpgrader existing = dataUpgraderMap.put(upgradeDataKey, dataUpgrader); if (existing != null) { this.logger.warn( "Duplicate IDataUpgrader PortalDataKey for {} Replacing {} with {}", new Object[] {upgradeDataKey, existing, dataUpgrader}); } } } catch (Exception exception) { logger.error("Failed to register data upgrader {}.", dataUpgrader, exception); } } this.portalDataUpgraders = Collections.unmodifiableMap(dataUpgraderMap); }
/** Run the import/update process on the data */ protected final void importOrUpgradeData( String systemId, PortalDataKey portalDataKey, XMLEventReader xmlEventReader) { // See if there is a registered importer for the data, if so import final IDataImporter<Object> dataImporterExporter = this.portalDataImporters.get(portalDataKey); if (dataImporterExporter != null) { this.logger.debug("Importing: {}", getPartialSystemId(systemId)); final Object data = unmarshallData(xmlEventReader, dataImporterExporter); dataImporterExporter.importData(data); this.logger.info("Imported : {}", getPartialSystemId(systemId)); return; } // No importer, see if there is an upgrader, if so upgrade final IDataUpgrader dataUpgrader = this.portalDataUpgraders.get(portalDataKey); if (dataUpgrader != null) { this.logger.debug("Upgrading: {}", getPartialSystemId(systemId)); // Convert the StAX stream to a DOM node, due to poor JDK support for StAX with XSLT final Node sourceNode; try { sourceNode = xmlUtilities.convertToDom(xmlEventReader); } catch (XMLStreamException e) { throw new RuntimeException("Failed to create StAXSource from original XML reader", e); } final DOMSource source = new DOMSource(sourceNode); final DOMResult result = new DOMResult(); final boolean doImport = dataUpgrader.upgradeData(source, result); if (doImport) { // If the upgrader didn't handle the import as well wrap the result DOM in a new Source and // start the import process over again final org.w3c.dom.Node node = result.getNode(); final PortalDataKey upgradedPortalDataKey = new PortalDataKey(node); if (this.logger.isTraceEnabled()) { this.logger.trace( "Upgraded: " + getPartialSystemId(systemId) + " to " + upgradedPortalDataKey + "\n\nSource XML: \n" + XmlUtilitiesImpl.toString(source.getNode()) + "\n\nResult XML: \n" + XmlUtilitiesImpl.toString(node)); } else { this.logger.info( "Upgraded: {} to {}", getPartialSystemId(systemId), upgradedPortalDataKey); } final DOMSource upgradedSource = new DOMSource(node, systemId); this.importData(upgradedSource, upgradedPortalDataKey); } else { this.logger.info("Upgraded and Imported: {}", getPartialSystemId(systemId)); } return; } // No importer or upgrader found, fail throw new IllegalArgumentException( "Provided data " + portalDataKey + " has no registered importer or upgrader support: " + systemId); }