/** * <a href="http://www.openolat.org"> * OpenOLAT - Online Learning and Training</a><br> * <p> * Licensed under the Apache License, Version 2.0 (the "License"); <br> * you may not use this file except in compliance with the License.<br> * You may obtain a copy of the License at the * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> * <p> * Unless required by applicable law or agreed to in writing,<br> * software distributed under the License is distributed on an "AS IS" BASIS, <br> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> * See the License for the specific language governing permissions and <br> * limitations under the License. * <p> * Initial code contributed and copyrighted by<br> * frentix GmbH, http://www.frentix.com * <p> */ package org.olat.admin.version; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.util.List; import java.util.Locale; import org.olat.admin.SystemAdminMainController; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.services.taskexecutor.TaskExecutorManager; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.elements.FormLink; import org.olat.core.gui.components.form.flexible.elements.StaticTextElement; import org.olat.core.gui.components.form.flexible.impl.FormBasicController; import org.olat.core.gui.components.form.flexible.impl.FormEvent; import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer; import org.olat.core.gui.components.link.Link; import org.olat.core.gui.components.progressbar.ProgressController; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController; import org.olat.core.gui.control.generic.modal.DialogBoxController; import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory; import org.olat.core.util.Util; import org.olat.core.util.async.ProgressDelegate; import org.olat.core.util.vfs.version.OrphanVersion; import org.olat.core.util.vfs.version.SimpleVersionConfig; import org.olat.core.util.vfs.version.VFSRevision; import org.olat.core.util.vfs.version.VersionsManager; /** * * Description:<br> * This is a controller to configure the SimpleVersionConfig, the configuration * of the versioning system for briefcase. * * <P> * Initial Date: 21 sept. 2009 <br> * * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ //fxdiff FXOLAT-127: file versions maintenance tool public class VersionMaintenanceForm extends FormBasicController implements ProgressDelegate { private FormLink cleanUpLink, pruneLink, showOrphanLink, orphanSize; private StaticTextElement orphanSizeEl; private CloseableModalController cmc; private OrphanVersionsController orphansController; private DialogBoxController confirmPrunehistoryBox; private DialogBoxController confirmDeleteOrphansBox; private ProgressController progressCtrl; private final VersionsManager versionsManager; private final TaskExecutorManager taskExecutorManager; public VersionMaintenanceForm(UserRequest ureq, WindowControl wControl) { super(ureq, wControl); // use combined translator from system admin main setTranslator(Util.createPackageTranslator(SystemAdminMainController.class, ureq.getLocale(), getTranslator())); versionsManager = CoreSpringFactory.getImpl(VersionsManager.class); taskExecutorManager = CoreSpringFactory.getImpl(TaskExecutorManager.class); initForm(ureq); } @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { // First add title and context help setFormTitle("version.maintenance.title"); setFormDescription("version.maintenance.intro"); orphanSizeEl = uifactory.addStaticTextElement("version.orphan.size", "version.orphan.size", "???", formLayout); FormLayoutContainer buttonsLayout = FormLayoutContainer.createButtonLayout("buttons", getTranslator()); formLayout.add(buttonsLayout); orphanSize = uifactory.addFormLink("version.orphan.size.calc", buttonsLayout, Link.BUTTON); showOrphanLink = uifactory.addFormLink("version.show.orphans", buttonsLayout, Link.BUTTON); cleanUpLink = uifactory.addFormLink("version.clean.up", buttonsLayout, Link.BUTTON); FormLayoutContainer buttons2Layout = FormLayoutContainer.createButtonLayout("buttons2", getTranslator()); formLayout.add(buttons2Layout); pruneLink = uifactory.addFormLink("version.prune.history", buttons2Layout, Link.BUTTON); } @Override protected void doDispose() { // } @Override protected void event(UserRequest ureq, Controller source, Event event) { if(source == orphansController) { cmc.deactivate(); cleanup(); } else if(source == confirmDeleteOrphansBox) { if (DialogBoxUIFactory.isYesEvent(event)) { doDeleteOrphans(ureq); } } else if(source == confirmPrunehistoryBox) { if (DialogBoxUIFactory.isYesEvent(event)) { doPruneHistory(ureq); } } else if(source == cmc) { cleanup(); } super.event(ureq, source, event); } private void cleanup() { removeAsListenerAndDispose(orphansController); removeAsListenerAndDispose(cmc); orphansController = null; cmc = null; } @Override protected void formOK(UserRequest ureq) { // } @Override protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { if(source == showOrphanLink) { List<OrphanVersion> orphans = versionsManager.orphans(); orphansController = new OrphanVersionsController(ureq, getWindowControl(), orphans); listenTo(orphansController); cmc = new CloseableModalController(getWindowControl(), "close", orphansController.getInitialComponent()); cmc.activate(); } else if(source == cleanUpLink) { String text = translate("confirm.delete.orphans"); confirmDeleteOrphansBox = activateYesNoDialog(ureq, null, text, confirmDeleteOrphansBox); } else if(source == pruneLink) { String text = translate("confirm.prune.history"); confirmPrunehistoryBox = activateYesNoDialog(ureq, null, text, confirmPrunehistoryBox); } else if (source == orphanSize) { orphanSizeEl.setValue(translate("version.orphan.size.calculating")); taskExecutorManager.execute(new Runnable() { public void run() { calculateOrphanSize(); } }); } super.formInnerEvent(ureq, source, event); } private void doDeleteOrphans(UserRequest ureq) { progressCtrl = new ProgressController(ureq, getWindowControl()); progressCtrl.setMessage(translate("version.clean.up")); progressCtrl.setPercentagesEnabled(false); progressCtrl.setUnitLabel(""); progressCtrl.setActual(0.0f); progressCtrl.setMax(100.0f); listenTo(progressCtrl); taskExecutorManager.execute(new Runnable() { public void run() { waitASecond(); versionsManager.deleteOrphans(VersionMaintenanceForm.this); } }); synchronized(this) { if(progressCtrl != null) { cmc = new CloseableModalController(getWindowControl(), null, progressCtrl.getInitialComponent(), true, null, false); cmc.activate(); listenTo(cmc); } } } private void doPruneHistory(UserRequest ureq) { progressCtrl = new ProgressController(ureq, getWindowControl()); progressCtrl.setMessage(translate("version.prune.history")); progressCtrl.setPercentagesEnabled(false); progressCtrl.setUnitLabel(""); progressCtrl.setMax(versionsManager.countDirectories()); listenTo(progressCtrl); taskExecutorManager.execute(new Runnable() { public void run() { waitASecond(); int numOfVersions = getNumOfVersions(); versionsManager.pruneHistory(numOfVersions, VersionMaintenanceForm.this); } }); synchronized(this) { if(progressCtrl != null) { cmc = new CloseableModalController(getWindowControl(), null, progressCtrl.getInitialComponent(), true, null, false); cmc.activate(); listenTo(cmc); } } } private final void waitASecond() { try { Thread.sleep(1000); } catch (InterruptedException e) { logError("Can't wait", e); } } public int getNumOfVersions() { SimpleVersionConfig config = (SimpleVersionConfig) CoreSpringFactory.getBean(SimpleVersionConfig.class); return config.getMaxNumberOfVersionsProperty(); } public final void calculateOrphanSize() { long size = 0l; List<OrphanVersion> orphans = versionsManager.orphans(); for(OrphanVersion orphan:orphans) { List<VFSRevision> revisions = orphan.getVersions().getRevisions(); if(revisions != null) { for(VFSRevision revision:revisions) { size += revision.getSize(); } } } String unit = "KB"; double humanSize = size / 1024.0d; if(humanSize > 1024) { humanSize /= 1024; unit = "MB"; } DecimalFormat sizeFormat = new DecimalFormat("#0.#", new DecimalFormatSymbols(Locale.ENGLISH)); String readableSize = sizeFormat.format(humanSize) + " " + unit; if(orphanSizeEl != null && !isDisposed()) { orphanSizeEl.setValue(readableSize); } } @Override public void setMax(float max) { if(progressCtrl != null && !progressCtrl.isDisposed()) { progressCtrl.setMax(max); } } @Override public void setActual(float value) { if(progressCtrl != null && !progressCtrl.isDisposed()) { progressCtrl.setActual(value); } } @Override public void setInfo(String message) { if(progressCtrl != null && !progressCtrl.isDisposed()) { progressCtrl.setInfo(message); } } @Override public synchronized void finished() { if(cmc != null && !cmc.isDisposed()) { cmc.deactivate(); } cleanup(); } }