/src/main/java/com/atlassian/confluence/plugin/upgrades/SpacehomeMigrationLongRunningTask.java
Java | 211 lines | 157 code | 40 blank | 14 comment | 10 complexity | 91d579da86b5bfb1666f18ebf6d88539 MD5 | raw file
- /*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
- package com.atlassian.confluence.plugin.upgrades;
- import com.atlassian.bonnie.Searchable;
- import com.atlassian.confluence.content.render.xhtml.DefaultConversionContext;
- import com.atlassian.confluence.content.render.xhtml.XhtmlException;
- import com.atlassian.confluence.content.render.xhtml.definition.MacroBody;
- import com.atlassian.confluence.content.render.xhtml.definition.PlainTextMacroBody;
- import com.atlassian.confluence.content.render.xhtml.definition.RichTextMacroBody;
- import com.atlassian.confluence.content.render.xhtml.migration.ContentDao;
- import com.atlassian.confluence.content.render.xhtml.migration.WikiToXhtmlMigrator;
- import com.atlassian.confluence.core.BodyType;
- import com.atlassian.confluence.core.ContentEntityManager;
- import com.atlassian.confluence.core.ContentEntityObject;
- import com.atlassian.confluence.core.DefaultSaveContext;
- import com.atlassian.confluence.core.persistence.hibernate.HibernateSessionManager;
- import com.atlassian.confluence.search.v2.ContentSearch;
- import com.atlassian.confluence.search.v2.ISearch;
- import com.atlassian.confluence.search.v2.InvalidSearchException;
- import com.atlassian.confluence.search.v2.SearchFieldNames;
- import com.atlassian.confluence.search.v2.SearchManager;
- import com.atlassian.confluence.search.v2.SearchManager.EntityVersionPolicy;
- import com.atlassian.confluence.search.v2.SearchQuery;
- import com.atlassian.confluence.search.v2.SearchResult;
- import com.atlassian.confluence.search.v2.lucene.LuceneSearchResults;
- import com.atlassian.confluence.search.v2.query.MacroUsageQuery;
- import com.atlassian.confluence.user.AuthenticatedUserThreadLocal;
- import com.atlassian.confluence.util.longrunning.ConfluenceAbstractLongRunningTask;
- import com.atlassian.confluence.xhtml.api.MacroDefinition;
- import com.atlassian.confluence.xhtml.api.MacroDefinitionUpdater;
- import com.atlassian.confluence.xhtml.api.XhtmlContent;
- import com.atlassian.sal.api.transaction.TransactionCallback;
- import com.atlassian.sal.api.transaction.TransactionTemplate;
- import com.atlassian.spring.container.ContainerManager;
- import com.atlassian.user.User;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.concurrent.atomic.AtomicBoolean;
- import net.sf.hibernate.HibernateException;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- /**
- *
- * @author dkjellin
- */
- public class SpacehomeMigrationLongRunningTask extends ConfluenceAbstractLongRunningTask {
- private static final Logger log = LoggerFactory.getLogger(SpacehomeMigrationLongRunningTask.class);
- private final User authenticatedUser;
- private final TransactionTemplate template;
- public SpacehomeMigrationLongRunningTask(User authenticatedUser, TransactionTemplate transactionTemplate) {
- this.authenticatedUser = authenticatedUser;
- template = transactionTemplate;
- }
- @Override
- protected void runInternal() {
- AuthenticatedUserThreadLocal.setUser(authenticatedUser);
- try {
- log.info("Starting spacehome macro migration");
- TransactionCallback callback = new TransactionCallback() {
- @Override
- public Object doInTransaction() {
- try {
- doMigration();
- return null;
- } catch (RuntimeException e) {
- e.printStackTrace();
- return e;
- }
- }
- };
- Object o = callback.doInTransaction();//template.execute(callback);
- if (o != null) {
- throw (RuntimeException) o;
- }
- } catch (RuntimeException e) {
- super.progress.setCompletedSuccessfully(false);
- log.error("Exception thrown while processing content: ", e);
- } finally {
- AuthenticatedUserThreadLocal.reset();
- }
- //construct search query
- //perform search
- //if count is > 200 batch
- // for each item in the batch do the "xhtmlcontent.updateMacroDefinition"
- //save item, flush+clear session repeat
- }
- @Override
- public String getName() {
- return "Spacehome macro long running migration";
- }
- private SearchQuery getQuery() {
- return new MacroUsageQuery("spacehome");
- }
- private void doMigration() {
- final SearchManager searchManager = (SearchManager) ContainerManager.getComponent("searchManager");
- final XhtmlContent xhtmlContent = (XhtmlContent) ContainerManager.getComponent("xhtmlContent");
- final WikiToXhtmlMigrator migrator = (WikiToXhtmlMigrator) ContainerManager.getComponent("wikiToXhtmlMigrator");
- final ContentDao contentEntityManager = (ContentDao) ContainerManager.getComponent("contentDao");
- final HibernateSessionManager sessionManager = (HibernateSessionManager)ContainerManager.getComponent("hibernateSessionManager");
- ISearch search = new ContentSearch(getQuery(), null, null, null);
- super.progress.setPercentage(0);
- List<SearchResult> searchResults;
- try {
- searchResults = searchManager.search(search, SearchFieldNames.createWithDefaultValues()).getAll();
- } catch (InvalidSearchException ex) {
- log.warn("Exception thrown when performing search to locate pages to migrate, aborting migration");
- return;
- }
- int totalSize = searchResults.size();
- int offset = 0;
- int newOffset = 0;
- int batchSize = 10;
- while (offset <= searchResults.size()) {
- newOffset = offset + batchSize;
- int endIndex = newOffset < searchResults.size() ? newOffset : searchResults.size();
- // convert search results to list of searchables
- final List<Searchable> searchables = searchManager.convertToEntities(new LuceneSearchResults(
- searchResults.subList(offset, endIndex), batchSize),
- EntityVersionPolicy.LATEST_VERSION);
- offset = newOffset;
- for (Searchable from : searchables) {
- if (from instanceof ContentEntityObject && ((ContentEntityObject) from).getBodyContent().getBodyType().equals(BodyType.XHTML)) {
- try {
-
- final AtomicBoolean updated = new AtomicBoolean();
- final ContentEntityObject ceo = (ContentEntityObject) from;
- final ContentEntityObject original = (ContentEntityObject) ceo.clone();
- try {
- String changedBody = xhtmlContent.updateMacroDefinitions(ceo.getBodyAsString(), new DefaultConversionContext(ceo.toPageContext()), new MacroDefinitionUpdater() {
- @Override
- public MacroDefinition update(MacroDefinition macroDefinition) {
- MacroBody macroBody = macroDefinition.getBody();
- if (macroBody instanceof PlainTextMacroBody) {
- List<RuntimeException> exceptions = new ArrayList<RuntimeException>();
- String body = migrator.migrate(macroBody.getBody(), ceo.toPageContext(), exceptions);
- if (!exceptions.isEmpty()) {
- log.error("Exceptions:" + exceptions);
- } else {
- updated.set(true);
- macroDefinition.setBody(new RichTextMacroBody(body));
- }
- }
- return macroDefinition;
- }
- });
- if (updated.get()) {
- ceo.setVersionComment("Converted to xthml format");
- ceo.setBodyAsString(changedBody);
- ceo.setLastModifierName(original.getLastModifierName());
- contentEntityManager.save(ceo, original);
- try {
- sessionManager.getSession().flush();
- } catch (HibernateException ex) {
- log.error("Hibernate blew up trying to flush the session:",ex);
-
- }
- }
- } catch (XhtmlException e) {
- log.error("Failed to upgrade page with id: " + ceo.getIdAsString() + " skipping and continuing.");
- }
- } catch (CloneNotSupportedException ex) {
- log.error("Clone not supported ",ex);
- }
- }
- super.progress.setPercentage(endIndex * 100 / totalSize);
- }
- }
- super.progress.setPercentage(100);
- super.progress.setCompletedSuccessfully(true);
- }
- }