/* GanymedeValidationTask.java This class goes through all objects in the database and checks to make sure all required fields are set in all objects. Created: 26 January 1999 Module By: Jonathan Abbey, jonabbey@arlut.utexas.edu ----------------------------------------------------------------------- Ganymede Directory Management System Copyright (C) 1996-2014 The University of Texas at Austin Ganymede is a registered trademark of The University of Texas at Austin Contact information Author Email: ganymede_author@arlut.utexas.edu Email mailing list: ganymede@arlut.utexas.edu US Mail: Computer Science Division Applied Research Laboratories The University of Texas at Austin PO Box 8029, Austin TX 78713-8029 Telephone: (512) 835-3200 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package arlut.csd.ganymede.server; import java.rmi.RemoteException; import java.util.Enumeration; import java.util.List; import java.util.Vector; import arlut.csd.Util.TranslationService; import arlut.csd.Util.VectorUtils; import arlut.csd.ganymede.common.NotLoggedInException; import arlut.csd.ganymede.common.ReturnVal; /*------------------------------------------------------------------------------ class GanymedeValidationTask ------------------------------------------------------------------------------*/ /** * <p>This task goes through all objects in the database and checks to * make sure all required fields are set in all objects.</p> */ public class GanymedeValidationTask implements Runnable { public static final boolean debug = true; /** * <p>TranslationService object for handling string localization in * the Ganymede server.</p> */ static final TranslationService ts = TranslationService.getTranslationService("arlut.csd.ganymede.server.GanymedeValidationTask"); // --- public GanymedeValidationTask() { } /** * * Just Do It (tm) * * @see java.lang.Runnable * */ public void run() { GanymedeSession mySession = null; boolean everythingsfine = true; Thread currentThread = java.lang.Thread.currentThread(); /* -- */ // "Validation Task: Starting" Ganymede.debug(ts.l("run.starting")); String error = GanymedeServer.lSemaphore.checkEnabled(); if (error != null) { // "Deferring validation task = semaphore disabled: {0}" Ganymede.debug(ts.l("run.disabled", error)); return; } try { try { mySession = new GanymedeSession("validation"); } catch (RemoteException ex) { // "Validation Task: Couldn''t establish session:\n{0}" Ganymede.debug(ts.l("run.nosession", Ganymede.stackTrace(ex))); return; } // we do each query on one object type.. we have to iterate // over all the object types defined in the server and scan // each for objects to be inactivated and/or removed. for (DBObjectBase base: Ganymede.db.bases()) { if (currentThread.isInterrupted()) { // "task interrupted." throw new InterruptedException(ts.l("run.interrupted")); } List<DBObject> objects = mySession.getDBSession().getTransactionalObjects(base.getTypeID()); if (debug) { // "Scanning base {0} for invalid objects" Ganymede.debug(ts.l("run.scanning", base.getName())); } for (DBObject object: objects) { if (currentThread.isInterrupted()) { throw new InterruptedException(ts.l("run.interrupted")); } Vector<String> missingFields = object.checkRequiredFields(); if (missingFields != null) { // "{0}:{1} is missing fields {2}" Ganymede.debug(ts.l("run.missing", base.getName(), object.getLabel(), VectorUtils.vectorString(missingFields))); everythingsfine = false; } ReturnVal retVal; try { retVal = object.getHook().consistencyCheck(object); if (!ReturnVal.didSucceed(retVal)) { String dialogText = retVal.getDialogText(); if (dialogText != null) { // {0}:{1} failed consistency check: {2} Ganymede.debug(ts.l("run.inconsistent", base.getName(), object.getLabel(), dialogText)); } else { // {0}:{1} failed consistency check Ganymede.debug(ts.l("run.inconsistent_notext", base.getName(), object.getLabel())); } everythingsfine = false; } } catch (Throwable ex) { // "{0}:{1} threw exception in consistencyCheck():\n{2}" Ganymede.debug(ts.l("run.exceptioned", base.getName(), object.getLabel(), Ganymede.stackTrace(ex))); everythingsfine = false; } try { retVal = object.validateFieldIntegrity(); // no merge since we don't return the retVal if (!ReturnVal.didSucceed(retVal)) { String dialogText = retVal.getDialogText(); if (dialogText != null) { // {0}:{1} failed field-level consistency check: {2} Ganymede.debug(ts.l("run.field_inconsistent", base.getName(), object.getLabel(), dialogText)); } else { // {0}:{1} failed field-level consistency check Ganymede.debug(ts.l("run.field_inconsistent_notext", base.getName(), object.getLabel())); } everythingsfine = false; } } catch (Throwable ex) { // "{0}:{1} threw exception in validateFieldIntegrity():\n{2}" Ganymede.debug(ts.l("run.field_exceptioned", base.getName(), object.getLabel(), Ganymede.stackTrace(ex))); everythingsfine = false; } } } if (everythingsfine) { // "Validation Task: All objects in database checked out fine." Ganymede.debug(ts.l("run.ok")); } else { // "Validation Task: Some objects had missing fields or were otherwise inconsistent." Ganymede.debug(ts.l("run.bad")); } } catch (InterruptedException ex) { // "GanymedeValidationTask interrupted by GanymedeScheduler, validation incomplete." Ganymede.debug(ts.l("run.interrupted_explanation")); } finally { if (mySession != null) { mySession.logout(); } } } }