0001: /*
0002: * Copyright (c) 2004-2006, Jean-François Brazeau. All rights reserved.
0003: *
0004: * Redistribution and use in source and binary forms, with or without
0005: * modification, are permitted provided that the following conditions are met:
0006: *
0007: * 1. Redistributions of source code must retain the above copyright notice,
0008: * this list of conditions and the following disclaimer.
0009: *
0010: * 2. Redistributions in binary form must reproduce the above copyright
0011: * notice, this list of conditions and the following disclaimer in the
0012: * documentation and/or other materials provided with the distribution.
0013: *
0014: * 3. The name of the author may not be used to endorse or promote products
0015: * derived from this software without specific prior written permission.
0016: *
0017: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0018: * IMPLIEDWARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0019: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0020: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0021: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
0022: * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
0023: * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0024: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
0025: * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
0026: * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0027: */
0028: package jfb.tools.activitymgr.core;
0029:
0030: import java.io.IOException;
0031: import java.io.InputStream;
0032: import java.io.OutputStream;
0033: import java.text.SimpleDateFormat;
0034: import java.util.ArrayList;
0035: import java.util.Arrays;
0036: import java.util.Calendar;
0037: import java.util.HashMap;
0038: import java.util.Iterator;
0039: import java.util.List;
0040:
0041: import javax.xml.parsers.ParserConfigurationException;
0042: import javax.xml.parsers.SAXParser;
0043: import javax.xml.parsers.SAXParserFactory;
0044:
0045: import jfb.tools.activitymgr.core.beans.Collaborator;
0046: import jfb.tools.activitymgr.core.beans.Contribution;
0047: import jfb.tools.activitymgr.core.beans.Duration;
0048: import jfb.tools.activitymgr.core.beans.Task;
0049: import jfb.tools.activitymgr.core.beans.TaskSearchFilter;
0050: import jfb.tools.activitymgr.core.beans.TaskSums;
0051: import jfb.tools.activitymgr.core.util.StringHelper;
0052: import jfb.tools.activitymgr.core.util.XmlHelper;
0053: import jfb.tools.activitymgr.core.util.XmlHelper.ModelMgrDelegate;
0054:
0055: import org.apache.log4j.Logger;
0056: import org.xml.sax.InputSource;
0057: import org.xml.sax.SAXException;
0058: import org.xml.sax.SAXParseException;
0059: import org.xml.sax.XMLReader;
0060:
0061: /**
0062: * Gestionnaire du modèle.
0063: *
0064: * <p>Les services offerts par cette classe garantissent l'intégrité du
0065: * modèle.</p>
0066: */
0067: public class ModelMgr {
0068:
0069: /** Logger */
0070: private static Logger log = Logger.getLogger(ModelMgr.class);
0071:
0072: /**
0073: * Initialise la connexion à la base de données.
0074: * @param driverName le nom du driver JDBC.
0075: * @param url l'URL de connexion au serveur.
0076: * @param user l'identifiant de connexion/
0077: * @param password le mot de passe de connexion.
0078: * @throws DbException levé en cas d'incident technique d'accès à la base.
0079: */
0080: public static void initDatabaseAccess(String driverName,
0081: String url, String user, String password)
0082: throws DbException {
0083: log.info("initDatabaseAccess(" + driverName + ", " + url + ", "
0084: + user + ")");
0085: DbMgr.initDatabaseAccess(driverName, url, user, password);
0086: }
0087:
0088: /**
0089: * Ferme la base de données.
0090: * @throws DbException levé en cas d'incident technique d'accès à la BDD.
0091: */
0092: public static void closeDatabaseAccess() throws DbException {
0093: DbMgr.closeDatabaseAccess();
0094: }
0095:
0096: /**
0097: * Vérifie si les tables existent dans le modèle.
0098: * @return un booléen indiquant si la table spécifiée existe dans le modèle.
0099: * @throws DbException levé en cas d'incident technique d'accès à la base.
0100: */
0101: public static boolean tablesExist() throws DbException {
0102: log.info("tablesExist()");
0103: DbTransaction tx = null;
0104: try {
0105: // Ouverture de la transaction
0106: tx = DbMgr.beginTransaction();
0107:
0108: // Test d'existence des tables
0109: boolean tablesExist = DbMgr.tablesExist(tx);
0110:
0111: // Commit et fin de la transaction
0112: DbMgr.endTransaction(tx);
0113: tx = null;
0114:
0115: // Retour du résultat
0116: return tablesExist;
0117: } finally {
0118: if (tx != null)
0119: try {
0120: DbMgr.endTransaction(tx);
0121: } catch (DbException ignored) {
0122: }
0123: }
0124: }
0125:
0126: /**
0127: * Crée les tables du modèle de données.
0128: * @throws DbException levé en cas d'incident technique d'accès à la base.
0129: */
0130: public static void createTables() throws DbException {
0131: log.info("createTables()");
0132: DbTransaction tx = null;
0133: try {
0134: // Ouverture de la transaction
0135: tx = DbMgr.beginTransaction();
0136:
0137: // Test d'existence des tables
0138: DbMgr.createTables(tx);
0139:
0140: // Commit et fin de la transaction
0141: DbMgr.commitTransaction(tx);
0142: DbMgr.endTransaction(tx);
0143: tx = null;
0144: } finally {
0145: if (tx != null)
0146: try {
0147: DbMgr.endTransaction(tx);
0148: } catch (DbException ignored) {
0149: }
0150: }
0151: }
0152:
0153: /**
0154: * Substitue une partie du chemin d'un groupe de tache et de leurs
0155: * sous-taches par un nouvelle valeur.
0156: * <p>Cette méthode est utilisée pour déplacer les sous-taches
0157: * d'une tache qui vient d'être déplacée.</p>
0158: * @param tx le contexte de transaction.
0159: * @param tasks les taches dont on veut changer le chemin.
0160: * @param oldPathLength la taille de la portion de chemin à changer.
0161: * @param newPath le nouveau chemin.
0162: * @throws DbException levé en cas d'incident technique d'accès à la base.
0163: */
0164: private static void changeTasksPaths(DbTransaction tx,
0165: Task[] tasks, int oldPathLength, String newPath)
0166: throws DbException {
0167: // Récupération de la liste des taches
0168: Iterator it = Arrays.asList(tasks).iterator();
0169: int newPathLength = newPath.length();
0170: StringBuffer buf = new StringBuffer(newPath);
0171: while (it.hasNext()) {
0172: Task task = (Task) it.next();
0173: log.debug("Updating path of task '" + task.getName() + "'");
0174: // Mise à jour des taches filles
0175: Task[] subTasks = DbMgr.getSubtasks(tx, task);
0176: if (subTasks.length > 0)
0177: changeTasksPaths(tx, subTasks, oldPathLength, newPath);
0178: // Puis mise à jour de la tache elle-même
0179: buf.setLength(newPathLength);
0180: buf.append(task.getPath().substring(oldPathLength));
0181: log.debug(" - old path : '" + task.getPath() + "'");
0182: task.setPath(buf.toString());
0183: log.debug(" - new path : '" + task.getPath() + "'");
0184: // Mise à jour
0185: DbMgr.updateTask(tx, task);
0186: }
0187: }
0188:
0189: /**
0190: * Vérifie si la tache spécifiée peut accueillir des sous-taches.
0191: * @param tx le contexte de transaction.
0192: * @param task la tache à controler.
0193: * @throws DbException levé en cas d'incident technique d'accès à la base.
0194: * @throws ModelException levé dans la cas ou la tache de destination ne peut recevoir de sous-tache.
0195: */
0196: private static void checkAcceptsSubtasks(DbTransaction tx, Task task)
0197: throws DbException, ModelException {
0198: // Rafraichissement des attributs de la tache
0199: task = DbMgr.getTask(tx, task.getId());
0200: // Une tâche qui admet déjà des sous-taches peut en admettre d'autres
0201: // La suite des controles n'est donc exécutée que si la tache n'admet
0202: // pas de sous-tâches
0203: if (task.getSubTasksCount() == 0) {
0204: // Une tache ne peut admettre une sous-tache que si elle
0205: // n'est pas déjà associée à un consommé (ie: à des contributions)
0206: long contribsNb = DbMgr.getContributionsNb(tx, task, null,
0207: null, null, null);
0208: if (contribsNb != 0)
0209: throw new ModelException("The task '" + task.getName()
0210: + "' is already used (contribsNb=" + contribsNb
0211: + "). It cannot accet sub tasks.");
0212: if (task.getBudget() != 0)
0213: throw new ModelException(
0214: "This task's 'budget' is not null. It cannot accept a sub task.");
0215: if (task.getInitiallyConsumed() != 0)
0216: throw new ModelException(
0217: "This task's 'initially consummed' is not null. It cannot accept a sub task.");
0218: if (task.getTodo() != 0)
0219: throw new ModelException(
0220: "This task's 'todo' is not null. It cannot accept a sub task.");
0221: }
0222: }
0223:
0224: /**
0225: * Vérifie si la tache spécifiée peut accueillir des sous-taches.
0226: * @param task la tache à controler.
0227: * @throws DbException levé en cas d'incident technique d'accès à la base.
0228: * @throws ModelException levé dans la cas ou la tache de destination ne peut recevoir de sous-tache.
0229: */
0230: public static void checkAcceptsSubtasks(Task task)
0231: throws DbException, ModelException {
0232: log.info("checkAcceptsSubtasks(" + task + ")");
0233: DbTransaction tx = null;
0234: try {
0235: // Ouverture de la transaction
0236: tx = DbMgr.beginTransaction();
0237:
0238: // Une tache ne peut admettre une sous-tache que si elle
0239: // n'est pas déjà associée à un consommé
0240: checkAcceptsSubtasks(tx, task);
0241:
0242: // Commit et fin de la transaction
0243: DbMgr.endTransaction(tx);
0244: tx = null;
0245: } finally {
0246: if (tx != null)
0247: try {
0248: DbMgr.endTransaction(tx);
0249: } catch (DbException ignored) {
0250: }
0251: }
0252: }
0253:
0254: /**
0255: * Vérifie que le chemin et le numéro de la tache en base de données
0256: * coincident avec la copie de la tache spécifiée.
0257: * @param tx le contexte de transaction.
0258: * @param task la copie de la tache en méméoire.
0259: * @throws DbException levé en cas d'incident technique d'accès à la base.
0260: * @throws ModelException levé dans la cas ou la tache de destination ne peut recevoir de sous-tache.
0261: */
0262: private static void checkTaskPathAndUpdateSubTasksCount(
0263: DbTransaction tx, Task task) throws ModelException,
0264: DbException {
0265: boolean noErrorOccured = false;
0266: Task _task = null;
0267: try {
0268: _task = DbMgr.getTask(tx, task.getId());
0269: if (_task == null)
0270: throw new ModelException(
0271: "Task does not exist in the database");
0272: if (!_task.getPath().equals(task.getPath()))
0273: throw new ModelException(
0274: "Task's path has changed in the database");
0275: if (_task.getNumber() != task.getNumber())
0276: throw new ModelException(
0277: "Task's number has changed in the database");
0278: task.setSubTasksCount(_task.getSubTasksCount());
0279: // Si aucune erreur n'est intervenue...
0280: noErrorOccured = true;
0281: } finally {
0282: if (!noErrorOccured && _task != null && task != null) {
0283: log.error("Task id = " + task.getId());
0284: log.error(" name = " + task.getName());
0285: log.error(" fullath = " + task.getPath() + "/"
0286: + task.getNumber());
0287: log.error(" db fullath = " + _task.getPath() + "/"
0288: + _task.getNumber());
0289: }
0290: }
0291: }
0292:
0293: /**
0294: * Vérifie l'unicité d'un login.
0295: * @param tx le contexte de transaction.
0296: * @param collaborator le collaborateur dont on veut vérifier l'unicité de login.
0297: * @throws DbException levé en cas d'incident technique d'accès à la base.
0298: * @throws ModelException levé dans le cas ou le ogin n'est pas unique.
0299: */
0300: private static void checkUniqueLogin(DbTransaction tx,
0301: Collaborator collaborator) throws DbException,
0302: ModelException {
0303: // Vérification de l'unicité
0304: Collaborator colWithSameLogin = DbMgr.getCollaborator(tx,
0305: collaborator.getLogin());
0306: // Vérification du login
0307: if (colWithSameLogin != null
0308: && !colWithSameLogin.equals(collaborator))
0309: throw new ModelException("login \""
0310: + colWithSameLogin.getLogin()
0311: + "\" is already affected to another user");
0312: }
0313:
0314: /**
0315: * Crée un collaborateur.
0316: * @param collaborator le collaborateur à créer.
0317: * @return le collaborateur après création.
0318: * @throws DbException levé en cas d'incident technique d'accès à la base.
0319: * @throws ModelException levé dans la cas ou la tache de destination ne peut recevoir de sous-tache.
0320: */
0321: public static Collaborator createCollaborator(
0322: Collaborator collaborator) throws DbException,
0323: ModelException {
0324: DbTransaction tx = null;
0325: try {
0326: // Ouverture de la transaction
0327: tx = DbMgr.beginTransaction();
0328:
0329: // Création du collaborateur
0330: collaborator = createCollaborator(tx, collaborator);
0331:
0332: // Commit et fin de la transaction
0333: DbMgr.commitTransaction(tx);
0334: DbMgr.endTransaction(tx);
0335: tx = null;
0336:
0337: // Retour du résultat
0338: return collaborator;
0339: } finally {
0340: if (tx != null)
0341: try {
0342: DbMgr.rollbackTransaction(tx);
0343: } catch (DbException ignored) {
0344: }
0345: if (tx != null)
0346: try {
0347: DbMgr.endTransaction(tx);
0348: } catch (DbException ignored) {
0349: }
0350: }
0351: }
0352:
0353: /**
0354: * Crée un collaborateur dans un contexte de transaction.
0355: * @param tx le contexte de transaction.
0356: * @param collaborator le collaborateur à créer.
0357: * @return le collaborateur après création.
0358: * @throws DbException levé en cas d'incident technique d'accès à la base.
0359: * @throws ModelException levé dans la cas ou la tache de destination ne peut recevoir de sous-tache.
0360: */
0361: private static Collaborator createCollaborator(DbTransaction tx,
0362: Collaborator collaborator) throws DbException,
0363: ModelException {
0364: log.info("createCollaborator(" + collaborator + ")");
0365: // Control de l'unicité du login
0366: checkUniqueLogin(tx, collaborator);
0367:
0368: // Création du collaborateur
0369: collaborator = DbMgr.createCollaborator(tx, collaborator);
0370:
0371: // Retour du résultat
0372: return collaborator;
0373: }
0374:
0375: /**
0376: * Crée une contribution.
0377: * @param contribution la contribution à créer.
0378: * @return la contribution après création.
0379: * @throws DbException levé en cas d'incident technique d'accès à la base.
0380: * @throws ModelException levé dans la cas ou la tache de destination ne peut recevoir de contribution.
0381: */
0382: public static Contribution createContribution(
0383: Contribution contribution) throws DbException,
0384: ModelException {
0385: DbTransaction tx = null;
0386: try {
0387: // Ouverture de la transaction
0388: tx = DbMgr.beginTransaction();
0389:
0390: // Création de la contribution
0391: contribution = createContribution(tx, contribution);
0392:
0393: // Commit et fin de la transaction
0394: DbMgr.commitTransaction(tx);
0395: DbMgr.endTransaction(tx);
0396: tx = null;
0397:
0398: // Retour du résultat
0399: return contribution;
0400: } finally {
0401: if (tx != null)
0402: try {
0403: DbMgr.rollbackTransaction(tx);
0404: } catch (DbException ignored) {
0405: }
0406: if (tx != null)
0407: try {
0408: DbMgr.endTransaction(tx);
0409: } catch (DbException ignored) {
0410: }
0411: }
0412: }
0413:
0414: /**
0415: * Crée une contribution dans un contexte de transaction.
0416: * @param tx le contexte de transaction.
0417: * @param contribution la contribution à créer.
0418: * @return la contribution après création.
0419: * @throws DbException levé en cas d'incident technique d'accès à la base.
0420: * @throws ModelException levé dans la cas ou la tache de destination ne peut recevoir de contribution.
0421: */
0422: private static Contribution createContribution(DbTransaction tx,
0423: Contribution contribution) throws DbException,
0424: ModelException {
0425: log.info("createContribution(" + contribution + ")");
0426: // La tache ne peut accepter une contribution que
0427: // si elle n'admet aucune sous-tache
0428: Task task = DbMgr.getTask(tx, contribution.getTaskId());
0429: if (task.getSubTasksCount() > 0)
0430: throw new ModelException(
0431: "This task has one or more sub tasks. It cannot accept a contribution.");
0432:
0433: // Création de la contribution
0434: contribution = DbMgr.createContribution(tx, contribution);
0435:
0436: // Retour du résultat
0437: return contribution;
0438: }
0439:
0440: /**
0441: * Crée une durée.
0442: * @param duration la durée à créer.
0443: * @return la durée créée.
0444: * @throws DbException levé en cas d'incident technique d'accès à la base.
0445: * @throws ModelException levé dans la cas ou la durée existe déjà.
0446: */
0447: public static Duration createDuration(Duration duration)
0448: throws DbException, ModelException {
0449: DbTransaction tx = null;
0450: try {
0451: // Ouverture de la transaction
0452: tx = DbMgr.beginTransaction();
0453:
0454: // Création
0455: duration = createDuration(tx, duration);
0456:
0457: // Commit et fin de la transaction
0458: DbMgr.commitTransaction(tx);
0459: DbMgr.endTransaction(tx);
0460: tx = null;
0461:
0462: // Retour du résultat
0463: return duration;
0464: } finally {
0465: if (tx != null)
0466: try {
0467: DbMgr.rollbackTransaction(tx);
0468: } catch (DbException ignored) {
0469: }
0470: if (tx != null)
0471: try {
0472: DbMgr.endTransaction(tx);
0473: } catch (DbException ignored) {
0474: }
0475: }
0476: }
0477:
0478: /**
0479: * Crée une durée dans un contexte de transaction.
0480: * @param tx le contexte de transaction.
0481: * @param duration la durée à créer.
0482: * @return la durée créée.
0483: * @throws DbException levé en cas d'incident technique d'accès à la base.
0484: * @throws ModelException levé dans la cas ou la durée existe déjà.
0485: */
0486: private static Duration createDuration(DbTransaction tx,
0487: Duration duration) throws DbException, ModelException {
0488: log.info("createDuration(" + duration + ")");
0489: // Vérification de l'unicité
0490: if (durationExists(tx, duration))
0491: throw new ModelException("This duration already exists");
0492:
0493: // Vérification de la non nullité
0494: if (duration.getId() == 0)
0495: throw new ModelException("A duration cannot be null");
0496:
0497: // Création
0498: duration = DbMgr.createDuration(tx, duration);
0499:
0500: // Retour du résultat
0501: return duration;
0502: }
0503:
0504: /**
0505: * Crée un nouveau collaborateur en générant automatiquement ses attributs.
0506: * @return le nouveau collaborateur.
0507: * @throws DbException levé en cas d'incident technique d'accès à la base.
0508: */
0509: public static Collaborator createNewCollaborator()
0510: throws DbException {
0511: log.info("createNewCollaborator()");
0512: DbTransaction tx = null;
0513: try {
0514: // Ouverture de la transaction
0515: tx = DbMgr.beginTransaction();
0516:
0517: // Le login doit être unique => il faut vérifier si
0518: // celui-ci n'a pas déjà été attribué
0519: int idx = 0;
0520: boolean unique = false;
0521: String newLogin = null;
0522: while (!unique) {
0523: newLogin = "<NEW"
0524: + (idx == 0 ? "" : String.valueOf(idx)) + ">";
0525: unique = DbMgr.getCollaborator(tx, newLogin) == null;
0526: idx++;
0527: }
0528: // Création du nouveau collaborateur
0529: Collaborator collaborator = new Collaborator();
0530: collaborator.setLogin(newLogin);
0531: collaborator.setFirstName("<NEW>");
0532: collaborator.setLastName("<NEW>");
0533: // Création en base
0534: collaborator = DbMgr.createCollaborator(tx, collaborator);
0535:
0536: // Commit et fin de la transaction
0537: DbMgr.commitTransaction(tx);
0538: DbMgr.endTransaction(tx);
0539: tx = null;
0540:
0541: // Retour du résultat
0542: return collaborator;
0543: } finally {
0544: if (tx != null)
0545: try {
0546: DbMgr.rollbackTransaction(tx);
0547: } catch (DbException ignored) {
0548: }
0549: if (tx != null)
0550: try {
0551: DbMgr.endTransaction(tx);
0552: } catch (DbException ignored) {
0553: }
0554: }
0555: }
0556:
0557: /**
0558: * Crée une nouvelle tache en générant un nom et un code.
0559: *
0560: * <p>Avant création, les caractéristiques de la tache de destination
0561: * sont controllées pour voir si elle peut accueillir des sous-taches.</p>
0562: *
0563: * <p>Cette méthode est synchronisée en raison de la génération du numéro de
0564: * la tache qui est déplacée à un autre chemin.</p>
0565: *
0566: * @param parentTask la tache parent de destination.
0567: * @return la tache crée.
0568: * @throws DbException levé en cas d'incident technique d'accès à la base.
0569: * @throws ModelException levé dans la cas ou la tache de destination ne peut recevoir de sous-tache.
0570: * @see jfb.tools.activitymgr.core.ModelMgr#checkAcceptsSubtasks(Task)
0571: */
0572: public static synchronized Task createNewTask(Task parentTask)
0573: throws DbException, ModelException {
0574: log.info("createNewTask(" + parentTask + ")");
0575: DbTransaction tx = null;
0576: try {
0577: // Ouverture de la transaction
0578: tx = DbMgr.beginTransaction();
0579:
0580: // Le code doit être unique => il faut vérifier si
0581: // celui-ci n'a pas déjà été attribué
0582: int idx = 0;
0583: boolean unique = false;
0584: String newCode = null;
0585: String taskPath = parentTask != null ? parentTask
0586: .getFullPath() : "";
0587: while (!unique) {
0588: newCode = "<N" + (idx == 0 ? "" : String.valueOf(idx))
0589: + ">";
0590: unique = DbMgr.getTask(tx, taskPath, newCode) == null;
0591: idx++;
0592: }
0593: // Création du nouveau collaborateur
0594: Task task = new Task();
0595: task.setName("<NEW>");
0596: task.setCode(newCode);
0597:
0598: // Création en base
0599: task = createTask(tx, parentTask, task);
0600:
0601: // Commit et fin de la transaction
0602: DbMgr.commitTransaction(tx);
0603: DbMgr.endTransaction(tx);
0604: tx = null;
0605:
0606: // Retour du résultat
0607: return task;
0608: } finally {
0609: if (tx != null)
0610: try {
0611: DbMgr.rollbackTransaction(tx);
0612: } catch (DbException ignored) {
0613: }
0614: if (tx != null)
0615: try {
0616: DbMgr.endTransaction(tx);
0617: } catch (DbException ignored) {
0618: }
0619: }
0620: }
0621:
0622: /**
0623: * Crée une nouvelle tache dans un contexte de transaction.
0624: *
0625: * <p>Avant création, les caractéristiques de la tache de destination
0626: * sont controllées pour voir si elle peut accueillir des sous-taches.</p>
0627: *
0628: * <p>Cette méthode est synchronisée en raison de la génération du numéro de
0629: * la tache qui est déplacée à un autre chemin.</p>
0630: *
0631: * @param tx le contexte de transaction.
0632: * @param parentTask la tache parent de destination.
0633: * @param task la tache à créer.
0634: * @return la tache crée.
0635: * @throws DbException levé en cas d'incident technique d'accès à la base.
0636: * @throws ModelException levé dans la cas ou la tache de destination ne peut recevoir de sous-tache.
0637: * @see jfb.tools.activitymgr.core.ModelMgr#checkAcceptsSubtasks(Task)
0638: */
0639: private synchronized static Task createTask(DbTransaction tx,
0640: Task parentTask, Task task) throws DbException,
0641: ModelException {
0642: log.info("createTask(" + parentTask + ", " + task + ")");
0643: // Une tache ne peut admettre une sous-tache que si elle
0644: // n'est pas déjà associée à un consommé
0645: if (parentTask != null)
0646: checkAcceptsSubtasks(tx, parentTask);
0647:
0648: // Check sur l'unicité du code pour le chemin considéré
0649: Task sameCodeTask = DbMgr.getTask(tx,
0650: parentTask != null ? parentTask.getFullPath() : "",
0651: task.getCode());
0652: if (sameCodeTask != null && !sameCodeTask.equals(task))
0653: throw new ModelException("This code is already in use");
0654:
0655: // Création de la tache
0656: task = DbMgr.createTask(tx, parentTask, task);
0657:
0658: // Retour du résultat
0659: return task;
0660: }
0661:
0662: /**
0663: * Crée une nouvelle tache.
0664: *
0665: * <p>Avant création, les caractéristiques de la tache de destination
0666: * sont controllées pour voir si elle peut accueillir des sous-taches.</p>
0667: *
0668: * @param parentTask la tache parent de destination.
0669: * @param task la tache à créer.
0670: * @return la tache crée.
0671: * @throws DbException levé en cas d'incident technique d'accès à la base.
0672: * @throws ModelException levé dans la cas ou la tache de destination ne peut recevoir de sous-tache.
0673: * @see jfb.tools.activitymgr.core.ModelMgr#checkAcceptsSubtasks(Task)
0674: */
0675: public static Task createTask(Task parentTask, Task task)
0676: throws DbException, ModelException {
0677: log.info("createTask(" + parentTask + ", " + task + ")");
0678: DbTransaction tx = null;
0679: try {
0680: // Ouverture de la transaction
0681: tx = DbMgr.beginTransaction();
0682:
0683: // Création de la tache
0684: task = createTask(tx, parentTask, task);
0685:
0686: // Commit et fin de la transaction
0687: DbMgr.commitTransaction(tx);
0688: DbMgr.endTransaction(tx);
0689: tx = null;
0690:
0691: // Retour du résultat
0692: return task;
0693: } finally {
0694: if (tx != null)
0695: try {
0696: DbMgr.rollbackTransaction(tx);
0697: } catch (DbException ignored) {
0698: }
0699: if (tx != null)
0700: try {
0701: DbMgr.endTransaction(tx);
0702: } catch (DbException ignored) {
0703: }
0704: }
0705: }
0706:
0707: /**
0708: * Vérifie si la durée existe en base.
0709: * @param tx le contexte de transaction.
0710: * @param duration la durée à vérifier.
0711: * @return un booléen indiquant si la durée existe.
0712: * @throws DbException levé en cas d'incident technique d'accès à la base.
0713: */
0714: private static boolean durationExists(DbTransaction tx,
0715: Duration duration) throws DbException {
0716: boolean exists = (DbMgr.getDuration(tx, duration.getId()) != null);
0717: return exists;
0718: }
0719:
0720: /**
0721: * Vérifie si la durée existe en base.
0722: * @param duration la durée à vérifier.
0723: * @return un booléen indiquant si la durée existe.
0724: * @throws DbException levé en cas d'incident technique d'accès à la base.
0725: */
0726: public static boolean durationExists(Duration duration)
0727: throws DbException {
0728: log.info("durationExists(" + duration + ")");
0729: DbTransaction tx = null;
0730: try {
0731: // Ouverture de la transaction
0732: tx = DbMgr.beginTransaction();
0733:
0734: // Calcul des sommes
0735: boolean exists = durationExists(tx, duration);
0736:
0737: // Fin de la transaction
0738: DbMgr.endTransaction(tx);
0739: tx = null;
0740:
0741: // Retour du résultat
0742: return exists;
0743: } finally {
0744: if (tx != null)
0745: try {
0746: DbMgr.endTransaction(tx);
0747: } catch (DbException ignored) {
0748: }
0749: }
0750: }
0751:
0752: /**
0753: * Importe le contenu d'un fichier XML.
0754: * @param in le flux depuis lequel est lu le flux XML.
0755: * @throws IOException levé en cas d'incident I/O lors de la lecture sur le flux d'entrée
0756: * @throws DbException levé en cas d'incident avec la base de données.
0757: * @throws ParserConfigurationException levé en cas de mauvaise configuration du parser XML.
0758: * @throws SAXException levé en cas d'erreur de mauvais format du fichier XML.
0759: * @throws ModelException levé en cas d'incohérence des données lors de l'import
0760: */
0761: public static void importFromXML(InputStream in)
0762: throws IOException, DbException,
0763: ParserConfigurationException, SAXException, ModelException {
0764: log.info("importFromXML()");
0765: DbTransaction tx = null;
0766: try {
0767: // Ouverture de la transaction
0768: tx = DbMgr.beginTransaction();
0769:
0770: // Création du gestionnaire de modèle de données
0771: ModelMgrDelegate modelMgrDelegate = new ModelMgrDelegate() {
0772: HashMap taskCache = new HashMap();
0773: HashMap collaboratorsCache = new HashMap();
0774:
0775: public Duration createDuration(DbTransaction tx,
0776: Duration duration) throws ModelException,
0777: DbException {
0778: return ModelMgr.createDuration(tx, duration);
0779: }
0780:
0781: public Collaborator createCollaborator(
0782: DbTransaction tx, Collaborator collaborator)
0783: throws DbException, ModelException {
0784: collaborator = ModelMgr.createCollaborator(tx,
0785: collaborator);
0786: collaboratorsCache.put(collaborator.getLogin(),
0787: collaborator);
0788: return collaborator;
0789: }
0790:
0791: public Task createTask(DbTransaction tx,
0792: Task parentTask, Task task) throws DbException,
0793: ModelException {
0794: task = ModelMgr.createTask(tx, parentTask, task);
0795: String taskPath = getTaskCodePath(tx, task);
0796: taskCache.put(taskPath, task);
0797: return task;
0798: }
0799:
0800: public Contribution createContribution(
0801: DbTransaction tx, Contribution contribution)
0802: throws DbException, ModelException {
0803: return ModelMgr
0804: .createContribution(tx, contribution);
0805: }
0806:
0807: public Task getTaskByCodePath(DbTransaction tx,
0808: String codePath) throws DbException,
0809: ModelException {
0810: Task task = (Task) taskCache.get(codePath);
0811: if (task == null) {
0812: task = ModelMgr.getTaskByCodePath(tx, codePath);
0813: taskCache.put(codePath, task);
0814: }
0815: return task;
0816: }
0817:
0818: public Collaborator getCollaborator(DbTransaction tx,
0819: String login) throws DbException {
0820: Collaborator collaborator = (Collaborator) collaboratorsCache
0821: .get(login);
0822: if (collaborator == null) {
0823: collaborator = DbMgr.getCollaborator(tx, login);
0824: collaboratorsCache.put(login, collaborator);
0825: }
0826: return collaborator;
0827: }
0828: };
0829:
0830: // Import des données
0831: SAXParserFactory factory = SAXParserFactory.newInstance();
0832: factory.setValidating(true);
0833: factory.setNamespaceAware(false);
0834: SAXParser parser = factory.newSAXParser();
0835: XMLReader reader = parser.getXMLReader();
0836: XmlHelper xmlHelper = new XmlHelper(modelMgrDelegate, tx);
0837: // La DTD est chargée dans le CLASSPATH
0838: reader.setEntityResolver(xmlHelper);
0839: // Positionnement du gestionnaire d'erreur
0840: reader.setErrorHandler(xmlHelper);
0841: // Positionnement du gestionnaire de contenu XML
0842: reader.setContentHandler(xmlHelper);
0843: // Parsing du fichier
0844: InputSource is = new InputSource(in);
0845: is.setSystemId(""); // Pour empêcher la levée d'erreur associé à l'URI de la DTD
0846: reader.parse(is);
0847:
0848: // Fermeture du flux de données
0849: in.close();
0850: in = null;
0851:
0852: // Commit et fin de la transaction
0853: DbMgr.commitTransaction(tx);
0854: DbMgr.endTransaction(tx);
0855: tx = null;
0856: } catch (SAXParseException e) {
0857: if (e.getCause() instanceof ModelException)
0858: throw (ModelException) e.getCause();
0859: else if (e.getCause() instanceof DbException)
0860: throw (DbException) e.getCause();
0861: else
0862: throw e;
0863: } finally {
0864: if (in != null)
0865: try {
0866: in.close();
0867: } catch (IOException ignored) {
0868: }
0869: if (tx != null)
0870: try {
0871: DbMgr.rollbackTransaction(tx);
0872: } catch (DbException ignored) {
0873: }
0874: if (tx != null)
0875: try {
0876: DbMgr.endTransaction(tx);
0877: } catch (DbException ignored) {
0878: }
0879: }
0880: }
0881:
0882: /**
0883: * Exporte le contenu de la base dans un fichier XML.
0884: * @param out le flux dans lequel est généré le flux XML.
0885: * @throws IOException levé en cas d'incident I/O lors de l'écriture sur le flux de sortie.
0886: * @throws DbException levé en cas d'incident avec la base de données.
0887: */
0888: public static void exportToXML(OutputStream out)
0889: throws IOException, DbException {
0890: log.info("exportToXML()");
0891: DbTransaction tx = null;
0892: try {
0893: // Ouverture de la transaction
0894: tx = DbMgr.beginTransaction();
0895:
0896: // Entête XML
0897: XmlHelper.println(out,
0898: "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
0899: XmlHelper.println(out,
0900: "<!DOCTYPE model SYSTEM \"activitymgr.dtd\">");
0901:
0902: // Ajout des sommes de controle
0903: Task[] rootTasks = DbMgr.getSubtasks(tx, null);
0904: if (rootTasks.length > 0) {
0905: XmlHelper.println(out, "<!-- ");
0906: XmlHelper.println(out, " Root tasks check sums :");
0907: for (int i = 0; i < rootTasks.length; i++) {
0908: Task rootTask = rootTasks[i];
0909: TaskSums sums = DbMgr.getTaskSums(tx, rootTask);
0910: XmlHelper.println(out, " * Root task[" + i
0911: + "]='/" + rootTask.getCode() + "' ("
0912: + rootTask.getName() + ")");
0913: XmlHelper.println(out, " - Budgets : "
0914: + (sums.getBudgetSum() / 100d));
0915: XmlHelper.println(out, " - InitiallyConsumed : "
0916: + (sums.getInitiallyConsumedSum() / 100d));
0917: XmlHelper.println(out, " - Consumed : "
0918: + (sums.getConsumedSum() / 100d));
0919: XmlHelper.println(out, " - Todo : "
0920: + (sums.getTodoSum() / 100d));
0921: XmlHelper.println(out, " - Contibutions nb : "
0922: + sums.getContributionsNb());
0923: }
0924: XmlHelper.println(out, " -->");
0925: }
0926:
0927: // Ajout du noeud racine
0928: XmlHelper.startXmlNode(out, "", XmlHelper.MODEL_NODE);
0929: final String INDENT = " ";
0930:
0931: // Exportation des durées
0932: Duration[] durations = DbMgr.getDurations(tx, false);
0933: if (durations.length > 0) {
0934: XmlHelper.startXmlNode(out, " ",
0935: XmlHelper.DURATIONS_NODE);
0936: for (int i = 0; i < durations.length; i++) {
0937: Duration duration = durations[i];
0938: XmlHelper.startXmlNode(out, " ",
0939: XmlHelper.DURATION_NODE);
0940: XmlHelper.printTextNode(out, INDENT,
0941: XmlHelper.VALUE_NODE, String
0942: .valueOf(duration.getId()));
0943: XmlHelper.printTextNode(out, INDENT,
0944: XmlHelper.IS_ACTIVE_NODE, String
0945: .valueOf(duration.getIsActive()));
0946: XmlHelper.endXmlNode(out, " ",
0947: XmlHelper.DURATION_NODE);
0948: }
0949: XmlHelper.endXmlNode(out, " ",
0950: XmlHelper.DURATIONS_NODE);
0951: }
0952: // Exportation des collaborateurs
0953: Collaborator[] collaborators = DbMgr.getCollaborators(tx,
0954: Collaborator.LOGIN_FIELD_IDX, true, false);
0955: HashMap collaboratorsLoginsMap = new HashMap();
0956: if (collaborators.length > 0) {
0957: XmlHelper.startXmlNode(out, " ",
0958: XmlHelper.COLLABORATORS_NODE);
0959: for (int i = 0; i < collaborators.length; i++) {
0960: Collaborator collaborator = collaborators[i];
0961: // Enregitrement du login dans le dictionnaire de logins
0962: collaboratorsLoginsMap.put(new Long(collaborator
0963: .getId()), collaborator.getLogin());
0964: XmlHelper.startXmlNode(out, " ",
0965: XmlHelper.COLLABORATOR_NODE);
0966: XmlHelper.printTextNode(out, INDENT,
0967: XmlHelper.LOGIN_NODE, collaborator
0968: .getLogin());
0969: XmlHelper.printTextNode(out, INDENT,
0970: XmlHelper.FIRST_NAME_NODE, collaborator
0971: .getFirstName());
0972: XmlHelper.printTextNode(out, INDENT,
0973: XmlHelper.LAST_NAME_NODE, collaborator
0974: .getLastName());
0975: XmlHelper.printTextNode(out, INDENT,
0976: XmlHelper.IS_ACTIVE_NODE,
0977: String.valueOf(collaborator.getIsActive()));
0978: XmlHelper.endXmlNode(out, " ",
0979: XmlHelper.COLLABORATOR_NODE);
0980: }
0981: XmlHelper.endXmlNode(out, " ",
0982: XmlHelper.COLLABORATORS_NODE);
0983: }
0984: // Exportation des taches
0985: HashMap tasksCodePathMap = new HashMap();
0986: exportSubTasksToXML(tx, out, INDENT, null, "",
0987: tasksCodePathMap);
0988: // Exportation des contributions
0989: Contribution[] contributions = DbMgr.getContributions(tx,
0990: null, null, null, null, null);
0991: if (contributions.length > 0) {
0992: XmlHelper.startXmlNode(out, " ",
0993: XmlHelper.CONTRIBUTIONS_NODE);
0994: for (int i = 0; i < contributions.length; i++) {
0995: Contribution contribution = contributions[i];
0996: XmlHelper.print(out, " <");
0997: XmlHelper.print(out, XmlHelper.CONTRIBUTION_NODE);
0998: XmlHelper.printTextAttribute(out,
0999: XmlHelper.YEAR_ATTRIBUTE, String
1000: .valueOf(contribution.getYear()));
1001: XmlHelper.printTextAttribute(out,
1002: XmlHelper.MONTH_ATTRIBUTE, String
1003: .valueOf(contribution.getMonth()));
1004: XmlHelper.printTextAttribute(out,
1005: XmlHelper.DAY_ATTRIBUTE, String
1006: .valueOf(contribution.getDay()));
1007: XmlHelper.printTextAttribute(out,
1008: XmlHelper.DURATION_ATTRIBUTE, String
1009: .valueOf(contribution
1010: .getDurationId()));
1011: XmlHelper.println(out, ">");
1012: XmlHelper.printTextNode(out, INDENT,
1013: XmlHelper.CONTRIBUTOR_REF_NODE,
1014: (String) collaboratorsLoginsMap
1015: .get(new Long(contribution
1016: .getContributorId())));
1017: XmlHelper.printTextNode(out, INDENT,
1018: XmlHelper.TASK_REF_NODE,
1019: (String) tasksCodePathMap.get(new Long(
1020: contribution.getTaskId())));
1021: XmlHelper.endXmlNode(out, " ",
1022: XmlHelper.CONTRIBUTION_NODE);
1023: }
1024: XmlHelper.endXmlNode(out, " ",
1025: XmlHelper.CONTRIBUTIONS_NODE);
1026: }
1027: XmlHelper.endXmlNode(out, "", "model");
1028: out.flush();
1029:
1030: // Fin de la transaction
1031: DbMgr.endTransaction(tx);
1032: tx = null;
1033: } finally {
1034: if (tx != null)
1035: try {
1036: DbMgr.endTransaction(tx);
1037: } catch (DbException ignored) {
1038: }
1039: }
1040: }
1041:
1042: /**
1043: * Ecrit les sous taches sous forme de XML dans le flux d'écriture.
1044: * @param tx le contexte de transaction.
1045: * @param out le flux d'écriture.
1046: * @param indent l'indentation.
1047: * @param parentTask la tache parent.
1048: * @param parentCodePath le chemin de la tache parente.
1049: * @param taskCodesPathMap cache contenant les taches indexées par leur chemin.
1050: * @throws IOException levé en cas d'incident I/O lors de l'écriture sur le flux de sortie.
1051: * @throws DbException levé en cas d'incident avec la base de données.
1052: */
1053: private static void exportSubTasksToXML(DbTransaction tx,
1054: OutputStream out, String indent, Task parentTask,
1055: String parentCodePath, HashMap taskCodesPathMap)
1056: throws IOException, DbException {
1057: Task[] tasks = DbMgr.getSubtasks(tx, parentTask);
1058: if (tasks.length > 0) {
1059: // Cas particulier pour la racine
1060: if (parentTask == null)
1061: XmlHelper.startXmlNode(out, " ", XmlHelper.TASKS_NODE);
1062: for (int i = 0; i < tasks.length; i++) {
1063: Task task = tasks[i];
1064: XmlHelper
1065: .startXmlNode(out, " ", XmlHelper.TASK_NODE);
1066: String taskCodePath = parentCodePath + "/"
1067: + task.getCode();
1068: // Enregistrement du chemin dans le dictionnaire de chemins
1069: taskCodesPathMap.put(new Long(task.getId()),
1070: taskCodePath);
1071: XmlHelper.printTextNode(out, indent,
1072: XmlHelper.PATH_NODE, taskCodePath);
1073: XmlHelper.printTextNode(out, indent,
1074: XmlHelper.NAME_NODE, task.getName());
1075: XmlHelper.printTextNode(out, indent,
1076: XmlHelper.BUDGET_NODE, String.valueOf(task
1077: .getBudget()));
1078: XmlHelper.printTextNode(out, indent,
1079: XmlHelper.INITIALLY_CONSUMED_NODE, String
1080: .valueOf(task.getInitiallyConsumed()));
1081: XmlHelper.printTextNode(out, indent,
1082: XmlHelper.TODO_NODE, String.valueOf(task
1083: .getTodo()));
1084: if (task.getComment() != null)
1085: XmlHelper.printTextNode(out, indent,
1086: XmlHelper.COMMENT_NODE, task.getComment());
1087: XmlHelper.endXmlNode(out, " ", XmlHelper.TASK_NODE);
1088: if (task.getSubTasksCount() > 0) {
1089: exportSubTasksToXML(tx, out, indent, task,
1090: taskCodePath, taskCodesPathMap);
1091: }
1092: }
1093: // Cas particulier pour la racine
1094: if (parentTask == null)
1095: XmlHelper.endXmlNode(out, " ", XmlHelper.TASKS_NODE);
1096: }
1097: }
1098:
1099: /**
1100: * @param collaboratorId l'identifiant du collaborateur recherché.
1101: * @return le collaborateur dont l'identifiant est spécifié.
1102: * @throws DbException levé en cas d'incident technique d'accès à la base.
1103: */
1104: public static Collaborator getCollaborator(long collaboratorId)
1105: throws DbException {
1106: log.info("getCollaborator(" + collaboratorId + ")");
1107: DbTransaction tx = null;
1108: try {
1109: // Ouverture de la transaction
1110: tx = DbMgr.beginTransaction();
1111:
1112: // Récupération des collaborateurs
1113: Collaborator collaborator = DbMgr.getCollaborator(tx,
1114: collaboratorId);
1115:
1116: // Fin de la transaction
1117: DbMgr.endTransaction(tx);
1118: tx = null;
1119:
1120: // Retour du résultat
1121: return collaborator;
1122: } finally {
1123: if (tx != null)
1124: try {
1125: DbMgr.endTransaction(tx);
1126: } catch (DbException ignored) {
1127: }
1128: }
1129: }
1130:
1131: /**
1132: * @return la liste des collaborateurs.
1133: * @throws DbException levé en cas d'incident technique d'accès à la base.
1134: */
1135: public static Collaborator[] getCollaborators() throws DbException {
1136: return getCollaborators(Collaborator.LOGIN_FIELD_IDX, true,
1137: false);
1138: }
1139:
1140: /**
1141: * @param orderByClauseFieldIndex index de l'attribut utilisé pour le tri.
1142: * @param ascendantSort booléen indiquant si le tri doit être ascendant.
1143: * @return la liste des collaborateurs actifs.
1144: * @throws DbException levé en cas d'incident technique d'accès à la base.
1145: */
1146: public static Collaborator[] getActiveCollaborators(
1147: int orderByClauseFieldIndex, boolean ascendantSort)
1148: throws DbException {
1149: return getCollaborators(orderByClauseFieldIndex, ascendantSort,
1150: true);
1151: }
1152:
1153: /**
1154: * @param orderByClauseFieldIndex index de l'attribut utilisé pour le tri.
1155: * @param ascendantSort booléen indiquant si le tri doit être ascendant.
1156: * @return la liste des collaborateurs.
1157: * @throws DbException levé en cas d'incident technique d'accès à la base.
1158: */
1159: public static Collaborator[] getCollaborators(
1160: int orderByClauseFieldIndex, boolean ascendantSort)
1161: throws DbException {
1162: return getCollaborators(orderByClauseFieldIndex, ascendantSort,
1163: false);
1164: }
1165:
1166: /**
1167: * @param orderByClauseFieldIndex index de l'attribut utilisé pour le tri.
1168: * @param ascendantSort booléen indiquant si le tri doit être ascendant.
1169: * @param onlyActiveCollaborators booléen indiquant si l'on ne doit retourner que
1170: * les collaborateurs actifs.
1171: * @return la liste des collaborateurs.
1172: * @throws DbException levé en cas d'incident technique d'accès à la base.
1173: */
1174: private static Collaborator[] getCollaborators(
1175: int orderByClauseFieldIndex, boolean ascendantSort,
1176: boolean onlyActiveCollaborators) throws DbException {
1177: log.info("getCollaborators()");
1178: DbTransaction tx = null;
1179: try {
1180: // Ouverture de la transaction
1181: tx = DbMgr.beginTransaction();
1182:
1183: // Récupération des collaborateurs
1184: Collaborator[] collaborators = DbMgr.getCollaborators(tx,
1185: orderByClauseFieldIndex, ascendantSort,
1186: onlyActiveCollaborators);
1187:
1188: // Fin de la transaction
1189: DbMgr.endTransaction(tx);
1190: tx = null;
1191:
1192: // Retour du résultat
1193: return collaborators;
1194: } finally {
1195: if (tx != null)
1196: try {
1197: DbMgr.endTransaction(tx);
1198: } catch (DbException ignored) {
1199: }
1200: }
1201: }
1202:
1203: /**
1204: * Retourne les contributions associées aux paramètres spécifiés.
1205: *
1206: * @param task la tâche associée aux contributions (facultative).
1207: * @param contributor le collaborateur associé aux contributions (facultatif).
1208: * @param year l'année (facultative).
1209: * @param month le mois (facultatif).
1210: * @param day le jour (facultatif).
1211: * @return les contributions.
1212: * @throws DbException levé en cas d'incident technique d'accès à la base.
1213: * @throws ModelException levé en cas d'incohérence des données en entrée avec le modèle.
1214: *
1215: * @see jfb.tools.activitymgr.core.DbMgr#getContributions(DbTransaction, Task, Collaborator, Integer, Integer, Integer)
1216: */
1217: public static Contribution[] getContributions(Task task,
1218: Collaborator contributor, Integer year, Integer month,
1219: Integer day) throws ModelException, DbException {
1220: log.info("getContributions(" + task + ", " + contributor + ", "
1221: + year + ", " + month + ", " + day + ")");
1222: DbTransaction tx = null;
1223: try {
1224: // Ouverture de la transaction
1225: tx = DbMgr.beginTransaction();
1226:
1227: // Vérification de la tache (le chemin de la tache doit être le bon pour
1228: // que le calcul le soit)
1229: if (task != null)
1230: checkTaskPathAndUpdateSubTasksCount(tx, task);
1231:
1232: // Récupération des durées
1233: Contribution[] result = DbMgr.getContributions(tx, task,
1234: contributor, year, month, day);
1235:
1236: // Fin de la transaction
1237: DbMgr.endTransaction(tx);
1238: tx = null;
1239:
1240: // Retour du résultat
1241: return result;
1242: } finally {
1243: if (tx != null)
1244: try {
1245: DbMgr.endTransaction(tx);
1246: } catch (DbException ignored) {
1247: }
1248: }
1249: }
1250:
1251: /**
1252: * Calcule le nombre des contributions associée aux paramètres spécifiés.
1253: *
1254: * @param task la tâche associée aux contributions (facultative).
1255: * @param contributor le collaborateur associé aux contributions (facultatif).
1256: * @param year l'année (facultative).
1257: * @param month le mois (facultatif).
1258: * @param day le jour (facultatif).
1259: * @return la seomme des contributions.
1260: * @throws DbException levé en cas d'incident technique d'accès à la base.
1261: * @throws ModelException levé en cas d'incohérence des données en entrée avec le modèle.
1262: *
1263: * @see jfb.tools.activitymgr.core.DbMgr#getContributionsNb(DbTransaction, Task, Collaborator, Integer, Integer, Integer)
1264: */
1265: public static long getContributionsNb(Task task,
1266: Collaborator contributor, Integer year, Integer month,
1267: Integer day) throws ModelException, DbException {
1268: log.info("getContributionsSum(" + task + ", " + contributor
1269: + ", " + year + ", " + month + ", " + day + ")");
1270: DbTransaction tx = null;
1271: try {
1272: // Ouverture de la transaction
1273: tx = DbMgr.beginTransaction();
1274:
1275: // Récupération du résultat
1276: long sum = getContributionsNb(tx, task, contributor, year,
1277: month, day);
1278:
1279: // Fin de la transaction
1280: DbMgr.endTransaction(tx);
1281: tx = null;
1282:
1283: // Retour du résultat
1284: return sum;
1285: } finally {
1286: if (tx != null)
1287: try {
1288: DbMgr.endTransaction(tx);
1289: } catch (DbException ignored) {
1290: }
1291: }
1292: }
1293:
1294: /**
1295: * Calcule le cumul des consommations associees aux contributions associée
1296: * pour les paramètres spécifiés.
1297: *
1298: * @param task la tâche associée aux contributions (facultative).
1299: * @param contributor le collaborateur associé aux contributions (facultatif).
1300: * @param year l'année (facultative).
1301: * @param month le mois (facultatif).
1302: * @param day le jour (facultatif).
1303: * @return la seomme des contributions.
1304: * @throws DbException levé en cas d'incident technique d'accès à la base.
1305: * @throws ModelException levé en cas d'incohérence des données en entrée avec le modèle.
1306: *
1307: * @see jfb.tools.activitymgr.core.DbMgr#getContributionsSum(DbTransaction, Task, Collaborator, Integer, Integer, Integer)
1308: */
1309: public static long getContributionsSum(Task task,
1310: Collaborator contributor, Integer year, Integer month,
1311: Integer day) throws ModelException, DbException {
1312: log.info("getContributionsSum(" + task + ", " + contributor
1313: + ", " + year + ", " + month + ", " + day + ")");
1314: DbTransaction tx = null;
1315: try {
1316: // Ouverture de la transaction
1317: tx = DbMgr.beginTransaction();
1318:
1319: // Récupération du résultat
1320: long sum = DbMgr.getContributionsSum(tx, task, contributor,
1321: year, month, day);
1322:
1323: // Fin de la transaction
1324: DbMgr.endTransaction(tx);
1325: tx = null;
1326:
1327: // Retour du résultat
1328: return sum;
1329: } finally {
1330: if (tx != null)
1331: try {
1332: DbMgr.endTransaction(tx);
1333: } catch (DbException ignored) {
1334: }
1335: }
1336: }
1337:
1338: /**
1339: * Calcule le nombre de contributions associée aux paramètres spécifiés dans un
1340: * contexte de transaction.
1341: *
1342: * @param tx le contexte de transaction.
1343: * @param task la tâche associée aux contributions (facultative).
1344: * @param contributor le collaborateur associé aux contributions (facultatif).
1345: * @param year l'année (facultative).
1346: * @param month le mois (facultatif).
1347: * @param day le jour (facultatif).
1348: * @return la seomme des contributions.
1349: * @throws DbException levé en cas d'incident technique d'accès à la base.
1350: * @throws ModelException levé en cas d'incohérence des données en entrée avec le modèle.
1351: *
1352: * @see jfb.tools.activitymgr.core.DbMgr#getContributionsSum(DbTransaction, Task, Collaborator, Integer, Integer, Integer)
1353: */
1354: public static long getContributionsNb(DbTransaction tx, Task task,
1355: Collaborator contributor, Integer year, Integer month,
1356: Integer day) throws ModelException, DbException {
1357: // Vérification de la tache (le chemin de la tache doit être le bon pour
1358: // que le calcul le soit)
1359: if (task != null)
1360: checkTaskPathAndUpdateSubTasksCount(tx, task);
1361:
1362: // Récupération du total
1363: long sum = DbMgr.getContributionsNb(tx, task, contributor,
1364: year, month, day);
1365:
1366: // Retour du résultat
1367: return sum;
1368: }
1369:
1370: /**
1371: * Retourne la liste des contributions associées à une tache, un collaborateur et à
1372: * un interval de temps donnés.
1373: *
1374: * <p>Un tableau dont la taille est égale au nombre de jours séparant les
1375: * deux dates spécifiées est retourné.
1376: *
1377: * @param contributor le collaborateur associé aux contributions.
1378: * @param task la tache associée aux contributions.
1379: * @param fromDate la date de départ.
1380: * @param toDate la date de fin.
1381: * @return la liste des contributions.
1382: * @throws DbException levé en cas d'incident technique d'accès à la base.
1383: * @throws ModelException levé dans le cas ou la date de fin spécifiée est antérieure
1384: * à la date de début spécifiée.
1385: */
1386: public static Contribution[] getDaysContributions(
1387: Collaborator contributor, Task task, Calendar fromDate,
1388: Calendar toDate) throws DbException, ModelException {
1389: log.info("getDaysContributions(" + contributor + ", " + task
1390: + ", " + StringHelper.toYYYYMMDD(fromDate) + ", "
1391: + StringHelper.toYYYYMMDD(toDate) + ")");
1392: DbTransaction tx = null;
1393: try {
1394: // Ouverture de la transaction
1395: tx = DbMgr.beginTransaction();
1396:
1397: // Préparation du résultat
1398: SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
1399: // Control sur la date
1400: if (fromDate.getTime().compareTo(toDate.getTime()) > 0)
1401: throw new ModelException(
1402: "'from date' must be before 'to date'");
1403: // Récupération des contributions
1404: Contribution[] contributionsArray = DbMgr.getContributions(
1405: tx, contributor, task, fromDate, toDate);
1406: // Classement des contributions
1407: List contributions = Arrays.asList(contributionsArray);
1408: ArrayList result = new ArrayList();
1409: for (Calendar date = (Calendar) fromDate.clone(); date
1410: .getTime().compareTo(toDate.getTime()) <= 0; date
1411: .add(Calendar.DATE, 1)) {
1412: log.debug(" - cal :" + sdf.format(date.getTime()));
1413: int n = contributions.size();
1414: boolean found = false;
1415: for (int i = 0; i < n && !found; i++) {
1416: Contribution contribution = (Contribution) contributions
1417: .get(i);
1418: found = contribution.getYear() == date
1419: .get(Calendar.YEAR)
1420: && contribution.getMonth() == (date
1421: .get(Calendar.MONTH) + 1)
1422: && contribution.getDay() == date
1423: .get(Calendar.DAY_OF_MONTH);
1424: if (found) {
1425: log.debug(" Adding :" + contribution);
1426: result.add(contribution);
1427: }
1428: }
1429: if (!found) {
1430: log.debug(" Adding : null");
1431: result.add(null);
1432: }
1433: }
1434:
1435: // Fin de la transaction
1436: DbMgr.endTransaction(tx);
1437: tx = null;
1438:
1439: // Retour du résultat
1440: return (Contribution[]) result
1441: .toArray(new Contribution[result.size()]);
1442: } finally {
1443: if (tx != null)
1444: try {
1445: DbMgr.endTransaction(tx);
1446: } catch (DbException ignored) {
1447: }
1448: }
1449: }
1450:
1451: /**
1452: * @return la liste des durées actives.
1453: * @throws DbException levé en cas d'incident technique d'accès à la base.
1454: */
1455: public static Duration[] getDurations() throws DbException {
1456: return getDurations(false);
1457: }
1458:
1459: /**
1460: * @return la liste des durées actives.
1461: * @throws DbException levé en cas d'incident technique d'accès à la base.
1462: */
1463: public static Duration[] getActiveDurations() throws DbException {
1464: return getDurations(true);
1465: }
1466:
1467: /**
1468: * @param onlyActiveCollaborators booléen indiquant si l'on ne doit retourner que
1469: * les collaborateurs actifs.
1470: * @return la liste des durées.
1471: * @throws DbException levé en cas d'incident technique d'accès à la base.
1472: */
1473: private static Duration[] getDurations(
1474: boolean onlyActiveCollaborators) throws DbException {
1475: log.info("getDurations()");
1476: DbTransaction tx = null;
1477: try {
1478: // Ouverture de la transaction
1479: tx = DbMgr.beginTransaction();
1480:
1481: // Récupération des durées
1482: Duration[] durations = DbMgr.getDurations(tx,
1483: onlyActiveCollaborators);
1484:
1485: // Fin de la transaction
1486: DbMgr.endTransaction(tx);
1487: tx = null;
1488:
1489: // Retour du résultat
1490: return durations;
1491: } finally {
1492: if (tx != null)
1493: try {
1494: DbMgr.endTransaction(tx);
1495: } catch (DbException ignored) {
1496: }
1497: }
1498: }
1499:
1500: /**
1501: * @param durationId identifiant de la durée.
1502: * @return la durée dont l'identifiant est spécifiée.
1503: * @throws DbException levé en cas d'incident technique d'accès à la base.
1504: */
1505: public static Duration getDuration(long durationId)
1506: throws DbException {
1507: log.info("getDurations()");
1508: DbTransaction tx = null;
1509: try {
1510: // Ouverture de la transaction
1511: tx = DbMgr.beginTransaction();
1512:
1513: // Récupération des durées
1514: Duration duration = DbMgr.getDuration(tx, durationId);
1515:
1516: // Fin de la transaction
1517: DbMgr.endTransaction(tx);
1518: tx = null;
1519:
1520: // Retour du résultat
1521: return duration;
1522: } finally {
1523: if (tx != null)
1524: try {
1525: DbMgr.endTransaction(tx);
1526: } catch (DbException ignored) {
1527: }
1528: }
1529: }
1530:
1531: /**
1532: * @param task la tache dont on veut connaitre la tache parent.
1533: * @return la tache parent d'une tache spécifiée.
1534: * @throws DbException levé en cas d'incident technique d'accès à la base.
1535: */
1536: public static Task getParentTask(Task task) throws DbException {
1537: log.info("getParentTask(" + task + ")");
1538: DbTransaction tx = null;
1539: try {
1540: // Ouverture de la transaction
1541: tx = DbMgr.beginTransaction();
1542:
1543: // Récupération de la tâche
1544: Task parentTask = DbMgr.getParentTask(tx, task);
1545:
1546: // Fin de la transaction
1547: DbMgr.endTransaction(tx);
1548: tx = null;
1549:
1550: // Retour du résultat
1551: return parentTask;
1552: } finally {
1553: if (tx != null)
1554: try {
1555: DbMgr.endTransaction(tx);
1556: } catch (DbException ignored) {
1557: }
1558: }
1559: }
1560:
1561: /**
1562: * @param parentTask la tache dont on veut connaître les sous-taches.
1563: * @return la liste des taches associées à un chemin donné.
1564: * @throws DbException levé en cas d'incident technique d'accès à la base.
1565: */
1566: public static Task[] getSubtasks(Task parentTask)
1567: throws DbException {
1568: log.info("getSubtasks(" + parentTask + ")");
1569: DbTransaction tx = null;
1570: try {
1571: // Ouverture de la transaction
1572: tx = DbMgr.beginTransaction();
1573:
1574: // Récupération des sous tâches
1575: Task[] subTasks = DbMgr.getSubtasks(tx, parentTask);
1576:
1577: // Fin de la transaction
1578: DbMgr.endTransaction(tx);
1579: tx = null;
1580:
1581: // Retour du résultat
1582: return subTasks;
1583: } finally {
1584: if (tx != null)
1585: try {
1586: DbMgr.endTransaction(tx);
1587: } catch (DbException ignored) {
1588: }
1589: }
1590: }
1591:
1592: /**
1593: * @param taskId l'identifiant de la tache recherchée.
1594: * @return la tache dont l'identifiant est spécifié.
1595: * @throws DbException levé en cas d'incident technique d'accès à la base.
1596: */
1597: public static Task getTask(long taskId) throws DbException {
1598: log.info("getTask(" + taskId + ")");
1599: DbTransaction tx = null;
1600: try {
1601: // Ouverture de la transaction
1602: tx = DbMgr.beginTransaction();
1603:
1604: // Récupération de la tâche
1605: Task task = DbMgr.getTask(tx, taskId);
1606:
1607: // Fin de la transaction
1608: DbMgr.endTransaction(tx);
1609: tx = null;
1610:
1611: // Retour du résultat
1612: return task;
1613: } finally {
1614: if (tx != null)
1615: try {
1616: DbMgr.endTransaction(tx);
1617: } catch (DbException ignored) {
1618: }
1619: }
1620: }
1621:
1622: /**
1623: * Retourn la liste des taches correspondant au filtre de recherche spécifié.
1624: * @param filter le filtre de recherche.
1625: * @return la liste des taches correspondant au filtre de recherche spécifié.
1626: * @throws DbException levé en cas d'incident technique d'accès à la base.
1627: */
1628: public static Task[] getTasks(TaskSearchFilter filter)
1629: throws DbException {
1630: log.info("getTasks(" + filter + ")");
1631: DbTransaction tx = null;
1632: try {
1633: // Ouverture de la transaction
1634: tx = DbMgr.beginTransaction();
1635:
1636: // Récupération de la tâche
1637: Task[] tasks = DbMgr.getTasks(tx, filter);
1638:
1639: // Fin de la transaction
1640: DbMgr.endTransaction(tx);
1641: tx = null;
1642:
1643: // Retour du résultat
1644: return tasks;
1645: } finally {
1646: if (tx != null)
1647: try {
1648: DbMgr.endTransaction(tx);
1649: } catch (DbException ignored) {
1650: }
1651: }
1652: }
1653:
1654: /**
1655: * @param taskPath le chemin de la tache recherchée.
1656: * @param taskCode le code de la tache recherchée.
1657: * @return la tache dont le code et la tache parent sont spécifiés.
1658: * @throws DbException levé en cas d'incident technique d'accès à la base.
1659: */
1660: public static Task getTask(String taskPath, String taskCode)
1661: throws DbException {
1662: log.info("getTask(" + taskPath + ", " + taskCode + ")");
1663: DbTransaction tx = null;
1664: try {
1665: // Ouverture de la transaction
1666: tx = DbMgr.beginTransaction();
1667:
1668: // Récupération de la tâche
1669: Task task = DbMgr.getTask(tx, taskPath, taskCode);
1670:
1671: // Fin de la transaction
1672: DbMgr.endTransaction(tx);
1673: tx = null;
1674:
1675: // Retour du résultat
1676: return task;
1677: } finally {
1678: if (tx != null)
1679: try {
1680: DbMgr.endTransaction(tx);
1681: } catch (DbException ignored) {
1682: }
1683: }
1684: }
1685:
1686: /**
1687: * Retourne la tache associée à un chemin construit à partir de
1688: * codes de taches.
1689: * @param codePath le chemin à base de code.
1690: * @return la tache trouvée.
1691: * @throws DbException levé en cas d'incident technique avec la base de données.
1692: * @throws ModelException levé dans le cas ou le chemin de tache est inconnu.
1693: */
1694: public static Task getTaskByCodePath(final String codePath)
1695: throws DbException, ModelException {
1696: log.info("getTaskByCodePath(" + codePath + ")");
1697: DbTransaction tx = null;
1698: try {
1699: // Ouverture de la transaction
1700: tx = DbMgr.beginTransaction();
1701:
1702: // Recherche de la tache
1703: Task task = getTaskByCodePath(tx, codePath);
1704:
1705: // Retour du résultat
1706: return task;
1707: } finally {
1708: if (tx != null)
1709: try {
1710: DbMgr.endTransaction(tx);
1711: } catch (DbException ignored) {
1712: }
1713: }
1714: }
1715:
1716: /**
1717: * Retourne la tache associée à un chemin construit à partir de
1718: * codes de taches.
1719: * @param tx le contexte de transaction.
1720: * @param codePath le chemin à base de code.
1721: * @return la tache trouvée.
1722: * @throws DbException levé en cas d'incident technique avec la base de données.
1723: * @throws ModelException levé dans le cas ou le chemin de tache est inconnu.
1724: */
1725: private static Task getTaskByCodePath(DbTransaction tx,
1726: final String codePath) throws DbException, ModelException {
1727: log.info("getTaskByCodePath(" + codePath + ")");
1728: if (!codePath.startsWith("/"))
1729: throw new ModelException("A valid path must start with '/'");
1730: // Recherche de la tache
1731: String subpath = codePath.trim().substring(1);
1732: log.debug("Processing task path '" + subpath + "'");
1733: Task task = null;
1734: while (subpath.length() > 0) {
1735: int idx = subpath.indexOf('/');
1736: String taskCode = idx >= 0 ? subpath.substring(0, idx)
1737: : subpath;
1738: String taskPath = task != null ? task.getFullPath() : "";
1739: subpath = idx >= 0 ? subpath.substring(idx + 1) : "";
1740: task = DbMgr.getTask(tx, taskPath, taskCode);
1741: if (task == null)
1742: throw new ModelException("Unknown task code path '"
1743: + codePath + "'");
1744: }
1745: log.debug("Found " + task);
1746:
1747: // Retour du résultat
1748: return task;
1749: }
1750:
1751: /**
1752: * @param collaborator le collaborateur.
1753: * @param fromDate date de début.
1754: * @param toDate date de fin.
1755: * @return la liste de taches associées au collaborateur entre les 2 dates spécifiées.
1756: * @throws DbException levé en cas d'incident technique d'accès à la base.
1757: */
1758: public static Task[] getTasks(Collaborator collaborator,
1759: Calendar fromDate, Calendar toDate) throws DbException {
1760: log.info("getTasks(" + collaborator + ", "
1761: + StringHelper.toYYYYMMDD(fromDate) + ", "
1762: + StringHelper.toYYYYMMDD(toDate) + ")");
1763: DbTransaction tx = null;
1764: try {
1765: // Ouverture de la transaction
1766: tx = DbMgr.beginTransaction();
1767:
1768: // Récupération des tâches
1769: Task[] tasks = DbMgr.getTasks(tx, collaborator, fromDate,
1770: toDate);
1771:
1772: // Fin de la transaction
1773: DbMgr.endTransaction(tx);
1774: tx = null;
1775:
1776: // Retour du résultat
1777: return tasks;
1778: } finally {
1779: if (tx != null)
1780: try {
1781: DbMgr.endTransaction(tx);
1782: } catch (DbException ignored) {
1783: }
1784: }
1785: }
1786:
1787: /**
1788: * Retourne la liste des taches associées aux chemins spécifiés.
1789: * @param codePaths la liste des chemins.
1790: * @return la liste des tâches.
1791: * @throws DbException
1792: * @throws ModelException levé dans le cas ou une tache n'existe pas.
1793: */
1794: public static Task[] getTasksByCodePath(String[] codePaths)
1795: throws DbException, ModelException {
1796: log.info("getTasksByCodePath(" + codePaths + ")");
1797: DbTransaction tx = null;
1798: try {
1799: // Ouverture de la transaction
1800: tx = DbMgr.beginTransaction();
1801:
1802: // Recherche des taches
1803: Task[] tasks = new Task[codePaths.length];
1804: for (int i = 0; i < codePaths.length; i++) {
1805: String codePath = codePaths[i].trim();
1806: log.debug("Searching task path '" + codePath + "'");
1807: Task task = ModelMgr.getTaskByCodePath(tx, codePath);
1808: // Enregistrement dans le tableau
1809: if (task == null)
1810: throw new ModelException("Unknown task : '"
1811: + codePath + "'");
1812: tasks[i] = task;
1813: }
1814:
1815: // Retour du résultat
1816: return tasks;
1817: } finally {
1818: if (tx != null)
1819: try {
1820: DbMgr.endTransaction(tx);
1821: } catch (DbException ignored) {
1822: }
1823: }
1824: }
1825:
1826: /**
1827: * @param task la tâche pour laquelle on souhaite connaître les totaux.
1828: * @return les totaux associés à une tache (consommé, etc.).
1829: * @throws ModelException levé dans le cas ou le chemin ou le numéro de la tache en base ne sont
1830: * pas ceux de la tache spécifiée.
1831: * @throws DbException levé en cas d'incident technique d'accès à la base.
1832: */
1833: public static TaskSums getTaskSums(Task task)
1834: throws ModelException, DbException {
1835: log.info("getTaskSums(" + task + ")");
1836: DbTransaction tx = null;
1837: try {
1838: // Ouverture de la transaction
1839: tx = DbMgr.beginTransaction();
1840:
1841: // Vérification de la tache (le chemin de la tache doit être le bon pour
1842: // que le calcul le soit)
1843: if (task != null)
1844: checkTaskPathAndUpdateSubTasksCount(tx, task);
1845:
1846: // Calcul des sommes
1847: TaskSums sums = DbMgr.getTaskSums(tx, task);
1848:
1849: // Fin de la transaction
1850: DbMgr.endTransaction(tx);
1851: tx = null;
1852:
1853: // Retour du résultat
1854: return sums;
1855: } finally {
1856: if (tx != null)
1857: try {
1858: DbMgr.endTransaction(tx);
1859: } catch (DbException ignored) {
1860: }
1861: }
1862: }
1863:
1864: /**
1865: * Construit le chemin de la tâche à partir des codes de tache.
1866: * @param task la tache dont on veut connaître le chemin.
1867: * @return le chemin.
1868: * @throws ModelException levé dans le cas ou le chemin ou le numéro de la tache
1869: * ont changé.
1870: * @throws DbException levé en cas d'incident technique avec la base de données.
1871: */
1872: public static String getTaskCodePath(Task task)
1873: throws ModelException, DbException {
1874: log.info("moveDownTask(" + task + ")");
1875: DbTransaction tx = null;
1876: try {
1877: // Ouverture de la transaction
1878: tx = DbMgr.beginTransaction();
1879:
1880: // Le chemin de la tache et son numéro ne doivent pas avoir changés
1881: // pour pouvoir invoquer cette méthode (la modification des attributs
1882: // n'est autorisée que pour les champs autres que le chemin et le numéro.
1883: checkTaskPathAndUpdateSubTasksCount(tx, task);
1884:
1885: // Construction du chemin
1886: String taskPath = getTaskCodePath(tx, task);
1887:
1888: // Commit et fin de la transaction
1889: DbMgr.endTransaction(tx);
1890: tx = null;
1891:
1892: // Retour du résultat
1893: return taskPath.toString();
1894: } finally {
1895: if (tx != null)
1896: try {
1897: DbMgr.endTransaction(tx);
1898: } catch (DbException ignored) {
1899: }
1900: }
1901: }
1902:
1903: /**
1904: * Construit le chemin de la tâche à partir des codes de tache.
1905: * @param tx le contexte de transaction.
1906: * @param task la tache dont on veut connaître le chemin.
1907: * @return le chemin.
1908: * @throws DbException levé en cas d'incident technique avec la base de données.
1909: */
1910: private static String getTaskCodePath(DbTransaction tx, Task task)
1911: throws DbException {
1912: // Construction
1913: StringBuffer taskPath = new StringBuffer("");
1914: Task cursor = task;
1915: while (cursor != null) {
1916: taskPath.insert(0, cursor.getCode());
1917: taskPath.insert(0, "/");
1918: cursor = DbMgr.getParentTask(tx, cursor);
1919: }
1920:
1921: // Retour du résultat
1922: return taskPath.toString();
1923: }
1924:
1925: /**
1926: * Déplace la tache d'un cran vers le bas.
1927: * <p>
1928: * Le chemin de la tache et son numéro ne doivent pas avoir changés
1929: * pour pouvoir invoquer cette méthode (la modification des attributs
1930: * n'est autorisée que pour les champs autres que le chemin et le numéro
1931: * de la tache.
1932: * </p>
1933: * @param task la tache à déplacer vers le bas.
1934: * @throws ModelException levé dans le cas ou le chemin ou le numéro de la tache
1935: * ont changé.
1936: * @throws DbException levé en cas d'incident technique avec la base de données.
1937: */
1938: public static void moveDownTask(Task task) throws ModelException,
1939: DbException {
1940: log.info("moveDownTask(" + task + ")");
1941: DbTransaction tx = null;
1942: try {
1943: // Ouverture de la transaction
1944: tx = DbMgr.beginTransaction();
1945:
1946: // Le chemin de la tache et son numéro ne doivent pas avoir changés
1947: // pour pouvoir invoquer cette méthode (la modification des attributs
1948: // n'est autorisée que pour les champs autres que le chemin et le numéro.
1949: checkTaskPathAndUpdateSubTasksCount(tx, task);
1950:
1951: // Recherche de la tache à descendre (incrémentation du numéro)
1952: byte taskToMoveUpNumber = (byte) (task.getNumber() + 1);
1953: Task taskToMoveUp = DbMgr.getTask(tx, task.getPath(),
1954: taskToMoveUpNumber);
1955: if (taskToMoveUp == null)
1956: throw new ModelException(
1957: "This task can not be moved down");
1958:
1959: // Inversion des taches
1960: toggleTasks(tx, task, taskToMoveUp);
1961:
1962: // Commit et fin de la transaction
1963: DbMgr.commitTransaction(tx);
1964: DbMgr.endTransaction(tx);
1965: tx = null;
1966: } finally {
1967: if (tx != null)
1968: try {
1969: DbMgr.rollbackTransaction(tx);
1970: } catch (DbException ignored) {
1971: }
1972: if (tx != null)
1973: try {
1974: DbMgr.endTransaction(tx);
1975: } catch (DbException ignored) {
1976: }
1977: }
1978: }
1979:
1980: /**
1981: * Déplace la tache vers un autre endroit dans la hiérarchie des taches.
1982: *
1983: * <p>Le chemin de la tache et son numéro ne doivent pas avoir changés
1984: * pour pouvoir invoquer cette méthode (la modification des attributs
1985: * n'est autorisée que pour les champs autres que le chemin et le numéro
1986: * de la tache.</p>
1987: *
1988: * <p>Cette méthode est synchronisée en raison de la génération du numéro de
1989: * la tache qui est déplacée à un autre chemin.</p>
1990: *
1991: * @param task la tache à déplacer.
1992: * @param destParentTask tache parent de destination.
1993: * @throws ModelException levé dans le cas ou le chemin ou le numéro de la tache
1994: * ont changé.
1995: * @throws DbException levé en cas d'incident technique avec la base de données.
1996: */
1997: public static synchronized void moveTask(Task task,
1998: Task destParentTask) throws ModelException, DbException {
1999: log.info("moveTask(" + task + ", " + destParentTask + ")");
2000: DbTransaction tx = null;
2001: try {
2002: // Ouverture de la transaction
2003: tx = DbMgr.beginTransaction();
2004:
2005: /**
2006: * Controles d'intégrité.
2007: */
2008:
2009: // Le chemin de la tache et son numéro ne doivent pas avoir changés
2010: // pour pouvoir invoquer cette méthode (la modification des attributs
2011: // n'est autorisée que pour les champs autres que le chemin et le numéro.
2012: checkTaskPathAndUpdateSubTasksCount(tx, task);
2013: if (destParentTask != null)
2014: checkTaskPathAndUpdateSubTasksCount(tx, destParentTask);
2015:
2016: // Control : la tache de destination ne doit pas être
2017: // une tache fille de la tache à déplacer
2018: Task cursor = destParentTask;
2019: while (cursor != null) {
2020: if (cursor.equals(task))
2021: throw new ModelException(
2022: "Moving a task under itself or one of its subtasks is not allowed.");
2023: cursor = DbMgr.getParentTask(tx, cursor);
2024: }
2025:
2026: // Une tache ne peut admettre une sous-tache que si elle
2027: // n'est pas déjà associée à un consommé
2028: if (destParentTask != null)
2029: checkAcceptsSubtasks(tx, destParentTask);
2030:
2031: // Le code de la tache à déplacer ne doit pas être en conflit
2032: // avec un code d'une autre tache fille de la tache parent
2033: // de destination
2034: String destPath = destParentTask != null ? destParentTask
2035: .getFullPath() : "";
2036: Task sameCodeTask = DbMgr.getTask(tx, destPath, task
2037: .getCode());
2038: if (sameCodeTask != null)
2039: throw new ModelException("The task's code '"
2040: + task.getCode()
2041: + "' already exists in the destination path.");
2042:
2043: /**
2044: * Déplacement de la tache.
2045: */
2046:
2047: // Récupération de la tache parent et des sous-taches
2048: // avant modification de son numéro et de son chemin
2049: String initialTaskFullPath = task.getFullPath();
2050: Task srcParentTask = DbMgr.getParentTask(tx, task);
2051: Task[] subTasksToMove = DbMgr.getSubtasks(tx, task);
2052:
2053: // Déplacement de la tache
2054: byte number = DbMgr.newTaskNumber(tx, destPath);
2055: task.setPath(destPath);
2056: task.setNumber(number);
2057: DbMgr.updateTask(tx, task);
2058:
2059: // Déplacement des sous-taches
2060: changeTasksPaths(tx, subTasksToMove, initialTaskFullPath
2061: .length(), task.getFullPath());
2062:
2063: // Reconstruction des numéros de tâches d'où la tâche provenait
2064: // et qui a laissé un 'trou' en étant déplacée
2065: rebuildSubtasksNumbers(tx, srcParentTask);
2066:
2067: // Commit et fin de la transaction
2068: DbMgr.commitTransaction(tx);
2069: DbMgr.endTransaction(tx);
2070: tx = null;
2071: } finally {
2072: if (tx != null)
2073: try {
2074: DbMgr.rollbackTransaction(tx);
2075: } catch (DbException ignored) {
2076: }
2077: if (tx != null)
2078: try {
2079: DbMgr.endTransaction(tx);
2080: } catch (DbException ignored) {
2081: }
2082: }
2083: }
2084:
2085: /**
2086: * Déplace la tache d'un cran vers le haut.
2087: * <p>
2088: * Le chemin de la tache et son numéro ne doivent pas avoir changés
2089: * pour pouvoir invoquer cette méthode (la modification des attributs
2090: * n'est autorisée que pour les champs autres que le chemin et le numéro
2091: * de la tache.
2092: * </p>
2093: * @param task la tache à déplacer vers le haut.
2094: * @throws ModelException levé dans le cas ou le chemin ou le numéro de la tache
2095: * ont changé.
2096: * @throws DbException levé en cas d'incident technique avec la base de données.
2097: */
2098: public static void moveUpTask(Task task) throws ModelException,
2099: DbException {
2100: log.info("moveUpTask(" + task + ")");
2101: DbTransaction tx = null;
2102: try {
2103: // Ouverture de la transaction
2104: tx = DbMgr.beginTransaction();
2105:
2106: // Le chemin de la tache et son numéro ne doivent pas avoir changés
2107: // pour pouvoir invoquer cette méthode (la modification des attributs
2108: // n'est autorisée que pour les champs autres que le chemin et le numéro.
2109: checkTaskPathAndUpdateSubTasksCount(tx, task);
2110:
2111: // Recherche de la tache à monter (décrémentation du numéro)
2112: byte taskToMoveDownNumber = (byte) (task.getNumber() - 1);
2113: Task taskToMoveDown = DbMgr.getTask(tx, task.getPath(),
2114: taskToMoveDownNumber);
2115: if (taskToMoveDown == null)
2116: throw new ModelException(
2117: "This task can not be moved up");
2118:
2119: // Inversion des taches
2120: toggleTasks(tx, task, taskToMoveDown);
2121:
2122: // Commit et fin de la transaction
2123: DbMgr.commitTransaction(tx);
2124: DbMgr.endTransaction(tx);
2125: tx = null;
2126: } finally {
2127: if (tx != null)
2128: try {
2129: DbMgr.rollbackTransaction(tx);
2130: } catch (DbException ignored) {
2131: }
2132: if (tx != null)
2133: try {
2134: DbMgr.endTransaction(tx);
2135: } catch (DbException ignored) {
2136: }
2137: }
2138: }
2139:
2140: /**
2141: * Reconstruit les numéros de taches pour un chemin donné (chemin complet
2142: * de la tache parent considérée).
2143: * @param tx le contexte de transaction.
2144: * @param parentTask la tache parent.
2145: * @throws DbException levé en cas d'incident technique d'accès à la base.
2146: */
2147: private static void rebuildSubtasksNumbers(DbTransaction tx,
2148: Task parentTask) throws DbException {
2149: // Récupération des sous-taches
2150: Task[] tasks = DbMgr.getSubtasks(tx, parentTask);
2151: for (int i = 0; i < tasks.length; i++) {
2152: Task task = tasks[i];
2153: byte taskNumber = task.getNumber();
2154: byte expectedNumber = (byte) (i + 1);
2155: if (taskNumber != expectedNumber) {
2156: Task[] subTasks = DbMgr.getSubtasks(tx, task);
2157: task.setNumber(expectedNumber);
2158: String fullPath = task.getFullPath();
2159: changeTasksPaths(tx, subTasks, fullPath.length(),
2160: fullPath);
2161: DbMgr.updateTask(tx, task);
2162: }
2163: }
2164: }
2165:
2166: /**
2167: * Supprime un collaborateur.
2168: * @param collaborator le collaborateur à supprimer.
2169: * @throws ModelException levé dans le cas ou le collaborateur est associé à des contributions en base.
2170: * @throws DbException levé en cas d'incident technique d'accès à la base.
2171: */
2172: public static void removeCollaborator(Collaborator collaborator)
2173: throws ModelException, DbException {
2174: log.info("removeCollaborator(" + collaborator + ")");
2175: DbTransaction tx = null;
2176: try {
2177: // Ouverture de la transaction
2178: tx = DbMgr.beginTransaction();
2179:
2180: // Vérification que le collaborateur n'est pas utilisé
2181: long contribsNb = getContributionsNb(tx, null,
2182: collaborator, null, null, null);
2183: if (contribsNb != 0)
2184: throw new ModelException("This collaborator has "
2185: + contribsNb + " contributions");
2186:
2187: // Suppression du collaborateur
2188: DbMgr.removeCollaborator(tx, collaborator);
2189:
2190: // Commit et fin de la transaction
2191: DbMgr.commitTransaction(tx);
2192: DbMgr.endTransaction(tx);
2193: tx = null;
2194: } finally {
2195: if (tx != null)
2196: try {
2197: DbMgr.rollbackTransaction(tx);
2198: } catch (DbException ignored) {
2199: }
2200: if (tx != null)
2201: try {
2202: DbMgr.endTransaction(tx);
2203: } catch (DbException ignored) {
2204: }
2205: }
2206: }
2207:
2208: /**
2209: * Supprime une contribution.
2210: * @param contribution la contribution à supprimer.
2211: * @throws DbException levé en cas d'incident technique d'accès à la base.
2212: */
2213: public static void removeContribution(Contribution contribution)
2214: throws DbException {
2215: log.info("removeContribution(" + contribution + ")");
2216: DbTransaction tx = null;
2217: try {
2218: // Ouverture de la transaction
2219: tx = DbMgr.beginTransaction();
2220:
2221: // Suppression de la contribution
2222: DbMgr.removeContribution(tx, contribution);
2223:
2224: // Commit et fin de la transaction
2225: DbMgr.commitTransaction(tx);
2226: DbMgr.endTransaction(tx);
2227: tx = null;
2228: } finally {
2229: if (tx != null)
2230: try {
2231: DbMgr.rollbackTransaction(tx);
2232: } catch (DbException ignored) {
2233: }
2234: if (tx != null)
2235: try {
2236: DbMgr.endTransaction(tx);
2237: } catch (DbException ignored) {
2238: }
2239: }
2240: }
2241:
2242: /**
2243: * Supprime des contributions.
2244: * @param contributions les contributions à supprimer.
2245: * @throws DbException levé en cas d'incident technique d'accès à la base.
2246: */
2247: public static void removeContributions(Contribution[] contributions)
2248: throws DbException {
2249: log.info("removeContributions(" + contributions + ")");
2250: DbTransaction tx = null;
2251: try {
2252: // Ouverture de la transaction
2253: tx = DbMgr.beginTransaction();
2254:
2255: // Suppression de la contribution
2256: for (int i = 0; i < contributions.length; i++)
2257: DbMgr.removeContribution(tx, contributions[i]);
2258:
2259: // Commit et fin de la transaction
2260: DbMgr.commitTransaction(tx);
2261: DbMgr.endTransaction(tx);
2262: tx = null;
2263: } finally {
2264: if (tx != null)
2265: try {
2266: DbMgr.rollbackTransaction(tx);
2267: } catch (DbException ignored) {
2268: }
2269: if (tx != null)
2270: try {
2271: DbMgr.endTransaction(tx);
2272: } catch (DbException ignored) {
2273: }
2274: }
2275: }
2276:
2277: /**
2278: * Supprime une durée du référentiel de durées.
2279: * @param duration la durée à supprimer.
2280: * @throws ModelException levé dans le cas ou la durée n'existe pas en base.
2281: * @throws DbException levé en cas d'incident technique d'accès à la base.
2282: */
2283: public static void removeDuration(Duration duration)
2284: throws ModelException, DbException {
2285: log.info("removeDuration(" + duration + ")");
2286: DbTransaction tx = null;
2287: try {
2288: // Ouverture de la transaction
2289: tx = DbMgr.beginTransaction();
2290:
2291: // Suppression
2292: removeDuration(tx, duration);
2293:
2294: // Commit et fin de la transaction
2295: DbMgr.commitTransaction(tx);
2296: DbMgr.endTransaction(tx);
2297: tx = null;
2298: } finally {
2299: if (tx != null)
2300: try {
2301: DbMgr.rollbackTransaction(tx);
2302: } catch (DbException ignored) {
2303: }
2304: if (tx != null)
2305: try {
2306: DbMgr.endTransaction(tx);
2307: } catch (DbException ignored) {
2308: }
2309: }
2310: }
2311:
2312: /**
2313: * Supprime une durée du référentiel de durées dans un contexte de transaction.
2314: * @param tx le contexte de transaction.
2315: * @param duration la durée à supprimer.
2316: * @throws ModelException levé dans le cas ou la durée n'existe pas en base.
2317: * @throws DbException levé en cas d'incident technique d'accès à la base.
2318: */
2319: private static void removeDuration(DbTransaction tx,
2320: Duration duration) throws ModelException, DbException {
2321: // Vérification de l'existance
2322: if (!durationExists(tx, duration))
2323: throw new ModelException("This duration does not exist");
2324:
2325: // Vérification de la non utilisation de la durée
2326: if (DbMgr.durationIsUsed(tx, duration))
2327: throw new ModelException(
2328: "This duration is used. It cannot be removed.");
2329:
2330: // Suppression
2331: DbMgr.removeDuration(tx, duration);
2332: }
2333:
2334: /**
2335: * Supprime une tache.
2336: *
2337: * <p>Cette méthode est synchronisée en raison de la modification potentielle du numéro de
2338: * certaines taches.</p>
2339: *
2340: * @param task la tache à supprimer.
2341: * @throws DbException levé en cas d'incident technique d'accès à la base.
2342: * @throws ModelException levé en cas de violation d'une contrainte d'intégrité du modèle.
2343: */
2344: public static synchronized void removeTask(Task task)
2345: throws DbException, ModelException {
2346: log.info("removeTask(" + task + ")");
2347: DbTransaction tx = null;
2348: try {
2349: // Ouverture de la transaction
2350: tx = DbMgr.beginTransaction();
2351:
2352: // Vérification de l'adéquation des attibuts de la tache avec les données en base
2353: checkTaskPathAndUpdateSubTasksCount(tx, task);
2354:
2355: // Vérification que la tache n'est pas utilisé
2356: long contribsNb = getContributionsNb(tx, task, null, null,
2357: null, null);
2358: if (contribsNb != 0)
2359: throw new ModelException(
2360: "This task and its subtasks have " + contribsNb
2361: + " contributions");
2362:
2363: // Récupération de la tâche parent pour reconstruction des
2364: // numéros de taches
2365: Task parentTask = DbMgr.getParentTask(tx, task);
2366:
2367: // Suppression des taches et sous taches
2368: DbMgr.removeTask(tx, task);
2369:
2370: // Reconstruction des numéros de taches
2371: rebuildSubtasksNumbers(tx, parentTask);
2372:
2373: // Commit et fin de la transaction
2374: DbMgr.commitTransaction(tx);
2375: DbMgr.endTransaction(tx);
2376: tx = null;
2377: } finally {
2378: if (tx != null)
2379: try {
2380: DbMgr.rollbackTransaction(tx);
2381: } catch (DbException ignored) {
2382: }
2383: if (tx != null)
2384: try {
2385: DbMgr.endTransaction(tx);
2386: } catch (DbException ignored) {
2387: }
2388: }
2389: }
2390:
2391: /**
2392: * Inverse deux taches dans l'arborescence des taches.
2393: * @param tx contexte de transaction.
2394: * @param task1 la 1° tache.
2395: * @param task2 la 2nde tache.
2396: * @throws DbException levé en cas d'incident technique d'accès à la base.
2397: */
2398: private static void toggleTasks(DbTransaction tx, Task task1,
2399: Task task2) throws DbException {
2400: byte task1InitialNumber = task1.getNumber();
2401: byte task2InitialNumber = task2.getNumber();
2402: String task1InitialFullpath = task1.getFullPath();
2403: String task2InitialFullpath = task2.getFullPath();
2404:
2405: // Récupération des taches filles de ces 2 taches
2406: Task[] task1subTasks = DbMgr.getSubtasks(tx, task1);
2407: Task[] task2subTasks = DbMgr.getSubtasks(tx, task2);
2408:
2409: // Changement des numéros de la tache 1 avec une valeur fictive
2410: task1.setNumber((byte) 0);
2411: DbMgr.updateTask(tx, task1);
2412: changeTasksPaths(tx, task1subTasks, task1InitialFullpath
2413: .length(), task1.getFullPath());
2414:
2415: // Changement des numéros de la tache 2
2416: task2.setNumber(task1InitialNumber);
2417: DbMgr.updateTask(tx, task2);
2418: changeTasksPaths(tx, task2subTasks, task2InitialFullpath
2419: .length(), task2.getFullPath());
2420:
2421: // Changement des numéros de la tache 1
2422: task1.setNumber(task2InitialNumber);
2423: DbMgr.updateTask(tx, task1);
2424: changeTasksPaths(tx, task1subTasks, task1InitialFullpath
2425: .length(), task1.getFullPath());
2426: }
2427:
2428: /**
2429: * Modifie les attributs d'un collaborateur.
2430: * @param collaborator le collaborateur à modifier.
2431: * @return le collaborateur modifié.
2432: * @throws DbException levé en cas d'incident technique d'accès à la base.
2433: * @throws ModelException levé en cas de non unicité du login.
2434: */
2435: public static Collaborator updateCollaborator(
2436: Collaborator collaborator) throws DbException,
2437: ModelException {
2438: log.info("updateCollaborator(" + collaborator + ")");
2439: DbTransaction tx = null;
2440: try {
2441: // Ouverture de la transaction
2442: tx = DbMgr.beginTransaction();
2443:
2444: // Control de l'unicité du login
2445: checkUniqueLogin(tx, collaborator);
2446:
2447: // Mise à jour des données
2448: collaborator = DbMgr.updateCollaborator(tx, collaborator);
2449:
2450: // Commit et fin de la transaction
2451: DbMgr.commitTransaction(tx);
2452: DbMgr.endTransaction(tx);
2453: tx = null;
2454:
2455: // Retour du résultat
2456: return collaborator;
2457: } finally {
2458: if (tx != null)
2459: try {
2460: DbMgr.rollbackTransaction(tx);
2461: } catch (DbException ignored) {
2462: }
2463: if (tx != null)
2464: try {
2465: DbMgr.endTransaction(tx);
2466: } catch (DbException ignored) {
2467: }
2468: }
2469: }
2470:
2471: /**
2472: * Met à jour une durée.
2473: * @param duration la durée à mettre à jour.
2474: * @return la durée mise à jour.
2475: * @throws DbException levé en cas d'incident technique d'accès à la base.
2476: */
2477: public static Duration updateDuration(Duration duration)
2478: throws DbException {
2479: log.info("updateDuration(" + duration + ")");
2480: DbTransaction tx = null;
2481: try {
2482: // Ouverture de la transaction
2483: tx = DbMgr.beginTransaction();
2484:
2485: // Mise à jour des données
2486: duration = DbMgr.updateDuration(tx, duration);
2487:
2488: // Commit et fin de la transaction
2489: DbMgr.commitTransaction(tx);
2490: DbMgr.endTransaction(tx);
2491: tx = null;
2492:
2493: // Retour du résultat
2494: return duration;
2495: } finally {
2496: if (tx != null)
2497: try {
2498: DbMgr.rollbackTransaction(tx);
2499: } catch (DbException ignored) {
2500: }
2501: if (tx != null)
2502: try {
2503: DbMgr.endTransaction(tx);
2504: } catch (DbException ignored) {
2505: }
2506: }
2507: }
2508:
2509: /**
2510: * Modifie les attributs d'une contribution.
2511: * @param contribution la contribution à modifier.
2512: * @return la contribution modifiée.
2513: * @throws DbException levé en cas d'incident technique d'accès à la base.
2514: */
2515: public static Contribution updateContribution(
2516: Contribution contribution) throws DbException {
2517: log.info("updateContribution(" + contribution + ")");
2518: DbTransaction tx = null;
2519: try {
2520: // Ouverture de la transaction
2521: tx = DbMgr.beginTransaction();
2522:
2523: // Mise à jour des données
2524: Contribution result = DbMgr.updateContribution(tx,
2525: contribution);
2526:
2527: // Commit et fin de la transaction
2528: DbMgr.commitTransaction(tx);
2529: DbMgr.endTransaction(tx);
2530: tx = null;
2531:
2532: // Retour du résultat
2533: return result;
2534: } finally {
2535: if (tx != null)
2536: try {
2537: DbMgr.rollbackTransaction(tx);
2538: } catch (DbException ignored) {
2539: }
2540: if (tx != null)
2541: try {
2542: DbMgr.endTransaction(tx);
2543: } catch (DbException ignored) {
2544: }
2545: }
2546: }
2547:
2548: /**
2549: * Change la tache d'une liste de contributions.
2550: * @param contributions la liste de contributions.
2551: * @param newContributionTask la tache à affecter.
2552: * @return la liste de contributions mise à jour.
2553: * @throws DbException levé en cas d'incident technique d'accès à la base.
2554: * @throws ModelException levé dans le cas où la tache cible ne peut
2555: * être acdepter de contribution.
2556: *
2557: */
2558: public static Contribution[] changeContributionTask(
2559: Contribution[] contributions, Task newContributionTask)
2560: throws DbException, ModelException {
2561: log.info("changeContributionTask(" + contributions + ", "
2562: + newContributionTask + ")");
2563: DbTransaction tx = null;
2564: try {
2565: // Ouverture de la transaction
2566: tx = DbMgr.beginTransaction();
2567:
2568: // La tache ne peut accepter une contribution que
2569: // si elle n'admet aucune sous-tache
2570: if (newContributionTask.getSubTasksCount() > 0)
2571: throw new ModelException(
2572: "This task has one or more sub tasks. It cannot accept a contribution.");
2573:
2574: // Mise à jour des identifiants de tâche
2575: for (int i = 0; i < contributions.length; i++) {
2576: Contribution contribution = contributions[i];
2577: DbMgr.changeContributionTask(tx, contribution,
2578: newContributionTask);
2579: }
2580:
2581: // Commit et fin de la transaction
2582: DbMgr.commitTransaction(tx);
2583: DbMgr.endTransaction(tx);
2584: tx = null;
2585:
2586: // Retour de la tache modifiée
2587: return contributions;
2588: } finally {
2589: if (tx != null)
2590: try {
2591: DbMgr.rollbackTransaction(tx);
2592: } catch (DbException ignored) {
2593: }
2594: if (tx != null)
2595: try {
2596: DbMgr.endTransaction(tx);
2597: } catch (DbException ignored) {
2598: }
2599: }
2600: }
2601:
2602: /**
2603: * Modifie une durée.
2604: * <p>
2605: * Pour pouvoir être modifiée, la durée ne doit pas être utilisée.
2606: * </p>
2607: * @param duration la durée à modifier.
2608: * @param newDuration la nouvelle valeur de la durée.
2609: * @return la durée modifiée.
2610: * @throws ModelException levé dans le cas ou la durée à changer est utilisée ou
2611: * dans le cas ou la nouvelle valeur pour la durée existe déjà dans le référentiel.
2612: * @throws DbException levé en cas d'incident technique avec la base de données.
2613: */
2614: public static Duration updateDuration(Duration duration,
2615: Duration newDuration) throws ModelException, DbException {
2616: log.info("updateDuration(" + duration + ", " + newDuration
2617: + ")");
2618: DbTransaction tx = null;
2619: try {
2620: // Si la nouvelle durée est égale à l'ancienne, il n'y a rien
2621: // à faire de plus!...
2622: if (!newDuration.equals(duration)) {
2623:
2624: // Ouverture de la transaction
2625: tx = DbMgr.beginTransaction();
2626:
2627: // Tentative de suppression de la durée
2628: removeDuration(tx, duration);
2629:
2630: // Insertion de la nouvelle durée
2631: createDuration(tx, newDuration);
2632:
2633: // Commit et fin de la transaction
2634: DbMgr.commitTransaction(tx);
2635: DbMgr.endTransaction(tx);
2636: tx = null;
2637: }
2638: // Retour de la tache modifiée
2639: return newDuration;
2640: } finally {
2641: if (tx != null)
2642: try {
2643: DbMgr.rollbackTransaction(tx);
2644: } catch (DbException ignored) {
2645: }
2646: if (tx != null)
2647: try {
2648: DbMgr.endTransaction(tx);
2649: } catch (DbException ignored) {
2650: }
2651: }
2652: }
2653:
2654: /**
2655: * Met à jour les attributs d'une tache en base.
2656: * <p>
2657: * Le chemin de la tache et son numéro ne doivent pas avoir changés
2658: * pour pouvoir invoquer cette méthode (la modification des attributs
2659: * n'est autorisée que pour les champs autres que le chemin et le numéro
2660: * de la tache.
2661: * </p>
2662: * @param task la tache à mettre à jour.
2663: * @return la tache mise à jour.
2664: * @throws ModelException levé dans le cas ou le chemin ou le numéro de la tache
2665: * ont changé.
2666: * @throws DbException levé en cas d'incident technique avec la base de données.
2667: */
2668: public static Task updateTask(Task task) throws ModelException,
2669: DbException {
2670: log.info("updateTask(" + task + ")");
2671: DbTransaction tx = null;
2672: try {
2673: // Ouverture de la transaction
2674: tx = DbMgr.beginTransaction();
2675:
2676: // Le chemin de la tache et son numéro ne doivent pas avoir changés
2677: // pour pouvoir invoquer cette méthode (la modification des attributs
2678: // n'est autorisée que pour les champs autres que le chemin et le numéro.
2679: checkTaskPathAndUpdateSubTasksCount(tx, task);
2680:
2681: // Check sur l'unicité du code pour le chemin considéré
2682: Task parentTask = DbMgr.getParentTask(tx, task);
2683: Task sameCodeTask = DbMgr.getTask(tx,
2684: parentTask != null ? parentTask.getFullPath() : "",
2685: task.getCode());
2686: if (sameCodeTask != null && !sameCodeTask.equals(task))
2687: throw new ModelException("This code is already in use");
2688:
2689: // Mise à jour des données
2690: task = DbMgr.updateTask(tx, task);
2691:
2692: // Commit et fin de la transaction
2693: DbMgr.commitTransaction(tx);
2694: DbMgr.endTransaction(tx);
2695: tx = null;
2696:
2697: // Retour de la tache modifiée
2698: return task;
2699: } finally {
2700: if (tx != null)
2701: try {
2702: DbMgr.rollbackTransaction(tx);
2703: } catch (DbException ignored) {
2704: }
2705: if (tx != null)
2706: try {
2707: DbMgr.endTransaction(tx);
2708: } catch (DbException ignored) {
2709: }
2710: }
2711: }
2712:
2713: }
|