001: /*
002: * Speedo: an implementation of JDO compliant personality on top of JORM
003: * generic I/O sub-system. Copyright (C) 2001-2004 France Telecom R&D
004: *
005: * This library is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU Lesser General Public License as published by the
007: * Free Software Foundation; either version 2 of the License, or (at your
008: * option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful, but WITHOUT
011: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
012: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
013: * for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public License
016: * along with this library; if not, write to the Free Software Foundation,
017: * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: *
019: * Release: 1.0
020: *
021: * Created on 1 mars 2004 @author fmillevi@yahoo.com
022: *
023: */
024: package org.objectweb.speedo.j2eedo.bo;
025:
026: import java.util.Collection;
027: import java.util.Hashtable;
028: import java.util.Iterator;
029: import java.util.StringTokenizer;
030: import java.util.Vector;
031:
032: import javax.jdo.JDOException;
033: import javax.jdo.JDOFatalException;
034: import javax.jdo.PersistenceManager;
035: import javax.jdo.Query;
036:
037: import org.objectweb.speedo.Alea;
038: import org.objectweb.speedo.j2eedo.common.PMHolder;
039: import org.objectweb.speedo.j2eedo.database.Address;
040: import org.objectweb.speedo.j2eedo.database.DatabaseObjectInterface;
041: import org.objectweb.speedo.j2eedo.database.Department;
042: import org.objectweb.speedo.j2eedo.database.Employee;
043: import org.objectweb.speedo.j2eedo.database.Project;
044: import org.objectweb.util.monolog.Monolog;
045: import org.objectweb.util.monolog.api.BasicLevel;
046: import org.objectweb.util.monolog.api.Logger;
047: import org.objectweb.util.monolog.api.LoggerFactory;
048:
049: /**
050: * This class handle each request on the <b>J2EEDO</b> application.
051: * The doAction() method performs the current requested action.
052: * <p>
053: * It starts and commits a transaction if needed
054: * </p>
055: * <p>
056: * Call the asked action. When the action in the
057: * {@link DatabaseImpl#actionArray action list}, the 3 local static lists of
058: * id (department, employee and project) are redefined.
059: * </p>
060: *
061: * @author fmillevi@yahoo.com
062: */
063: public class DatabaseImpl {
064: /**
065: * Defines the action <code>PARAMETER_PING</code><b> its value is ("ping")</b>
066: * <p>
067: * This action is use just to check if the application can be reached
068: * </p>
069: */
070: final public static String PARAMETER_PING = "ping";
071: /**
072: * Defines the action <code>PARAMETER_NEW_DEPARTMENT</code><b> its value is
073: * ("newDept")</b>
074: * <p>
075: * This action Creates a new department and some new employees (random
076: * number defined between 10 and 70).
077: * </p>
078: *
079: * @see DepartmentFactory#MIN_EMPLOYEE_PER_DEPARTMENT
080: * @see DepartmentFactory#MAX_EMPLOYEE_PER_DEPARTMENT
081: * @see DepartmentFactory#newDepartmentWithEmployees
082: */
083: final public static String PARAMETER_NEW_DEPARTMENT = "newDept";
084: /**
085: * Defines the action <code>PARAMETER_NEW_PROJECT</code><b> its value is
086: * ("newProj")</b>
087: * <p>
088: * This action Creates a new project and affect few employees (random
089: * number defined between 5 and 20).
090: * </p>
091: *
092: * @see ProjectFactory#MIN_MEMBER_PER_PROJECT
093: * @see ProjectFactory#MAX_MEMBER_PER_PROJECT
094: * @see ProjectFactory#newProjectWithEmployees
095: */
096: final public static String PARAMETER_NEW_PROJECT = "newProj";
097: /**
098: * Defines the action <code>PARAMETER_NEW_EMPLOYEE</code><b> its value is
099: * ("newEmp")</b>
100: * <p>
101: * Selects one of the known departments and creates a new employee.
102: * </p>
103: * @see EmployeeFactory#newEmployee
104: */
105: final public static String PARAMETER_NEW_EMPLOYEE = "newEmp";
106: /**
107: * Defines the action <code>PARAMETER_SET_BOSS</code><b> its value is
108: * ("setDeptBoss")</b>
109: * @see DepartmentFactory#setManagerForADepartment()
110: */
111: final public static String PARAMETER_SET_BOSS = "setDeptBoss";
112: /**
113: * Defines the action <code>PARAMETER_REM_EMPLOYEE</code><b> its value is
114: * ("delEmployee")</b>
115: * @see EmployeeFactory#deleteEmployee
116: */
117: final public static String PARAMETER_REM_EMPLOYEE = "delEmployee";
118: /**
119: * Defines the action <code>PARAMETER_REM_PROJECT</code><b> its value is
120: * ("delProject")</b>
121: * @see ProjectFactory#deleteProject
122: */
123: final public static String PARAMETER_REM_PROJECT = "delProject";
124: /**
125: * Defines the action <code>PARAMETER_SPLIT_PROJECT</code><b> its value is
126: * ("splitProject")</b>
127: * @see ProjectFactory#splitProject
128: */
129: final public static String PARAMETER_SPLIT_PROJECT = "splitProject";
130: /**
131: * Defines the action <code>PARAMETER_SPLIT_DEPARTMENT</code><b> its value is
132: * ("splitDepartment")</b>
133: * @see DepartmentFactory#splitDepartment
134: */
135: final public static String PARAMETER_SPLIT_DEPARTMENT = "splitDepartment";
136: /**
137: * Defines the action <code>PARAMETER_MERGE_DEPARTMENT</code><b> its value is
138: * ("mergeDept")</b>
139: * @see DepartmentFactory#mergeDepartment
140: */
141: final public static String PARAMETER_MERGE_DEPARTMENT = "mergeDept";
142: /**
143: * Defines the action <code>PARAMETER_INCREASE_SALARY</code><b> its value is
144: * ("incSalary")</b> for good folsk only...
145: * @see EmployeeFactory#increaseSalary()
146: */
147: final public static String PARAMETER_INCREASE_SALARY = "incSalary";
148: /**
149: * Defines the action <code>PARAMETER_GET_DEPARTMENT</code><b> its value is
150: * ("getDepartment")</b>
151: * @see DepartmentFactory#getDepartment()
152: */
153: final public static String PARAMETER_GET_DEPARTMENT = "getDepartment";
154: /**
155: * Defines the action <code>PARAMETER_GET_PROJECT</code><b> its value is
156: * ("getProject")</b>
157: * @see ProjectFactory#getProject()
158: */
159: final public static String PARAMETER_GET_PROJECT = "getProject";
160: /**
161: * Defines the action <code>PARAMETER_GET_EMPLOYEE</code><b> its value is
162: * ("getEmployee")</b>
163: * @see EmployeeFactory#getEmployees()
164: */
165: final public static String PARAMETER_GET_EMPLOYEE = "getEmployee";
166: /**
167: * Defines the action <code>PARAMETER_QUERY_PROJECTS</code><b> its value is
168: * ("queryProjects")</b>
169: * <p>
170: * Performs one of the four queries:
171: * <ul>
172: * <li>Get employee by its id,</li>
173: * <li>Get employees between min and max,</li>
174: * <li>Get employees having the same manager,</li>
175: * <li>Get employees member of a project.</li>
176: * </ul>
177: * </p>
178: * @see EmployeeFactory#getEmployees()
179: */
180: final public static String PARAMETER_QUERY_PROJECTS = "queryProjects";
181: /**
182: * Defines the action <code>PARAMETER_QUERY_EMPLOYEES</code><b> its value is
183: * ("queryEmployees")</b>
184: * <p>
185: * Performs one of the two queries:
186: * <ul>
187: * <li>Get project by its id,</li>
188: * <li>Get projects by member.</li>
189: * </ul>
190: * </p>
191: * @see ProjectFactory#getProjects()
192: */
193: final public static String PARAMETER_QUERY_EMPLOYEES = "queryEmployees";
194:
195: final public static String PARAMETER_EVICTALL = "evictall";
196: /**
197: * The String array <code>actionArray</code> gives the liste of actions
198: * avalaibles
199: */
200: final public static String actionArray[] = {
201: DatabaseImpl.PARAMETER_NEW_DEPARTMENT,
202: DatabaseImpl.PARAMETER_NEW_PROJECT,
203: DatabaseImpl.PARAMETER_NEW_EMPLOYEE,
204: DatabaseImpl.PARAMETER_SET_BOSS,
205: DatabaseImpl.PARAMETER_REM_EMPLOYEE,
206: DatabaseImpl.PARAMETER_REM_PROJECT,
207: DatabaseImpl.PARAMETER_SPLIT_PROJECT,
208: DatabaseImpl.PARAMETER_SPLIT_DEPARTMENT,
209: DatabaseImpl.PARAMETER_MERGE_DEPARTMENT,
210: DatabaseImpl.PARAMETER_INCREASE_SALARY,
211: DatabaseImpl.PARAMETER_GET_DEPARTMENT,
212: DatabaseImpl.PARAMETER_GET_PROJECT,
213: DatabaseImpl.PARAMETER_GET_EMPLOYEE,
214: DatabaseImpl.PARAMETER_QUERY_PROJECTS,
215: DatabaseImpl.PARAMETER_QUERY_EMPLOYEES,
216: DatabaseImpl.PARAMETER_PING };
217: final public static int READ = 1;
218: final public static int WRITE = 0;
219: /**
220: * The double dimension array <code>actionWeightArray</code> gives for
221: * each action the relative read and write weight
222: *
223: * @see #actionArray
224: */
225: final public static int actionWeightArray[][] = { //{write,read}
226: { 4, 0 }, //DatabaseImpl.PARAMETER_NEW_DEPARTMENT,
227: { 5, 3 }, //DatabaseImpl.PARAMETER_NEW_PROJECT,
228: { 1, 1 }, //DatabaseImpl.PARAMETER_NEW_EMPLOYEE,
229: { 4, 2 }, //DatabaseImpl.PARAMETER_SET_BOSS,
230: { 1, 1 }, //DatabaseImpl.PARAMETER_REM_EMPLOYEE,
231: { 4, 2 }, //DatabaseImpl.PARAMETER_REM_PROJECT,
232: { 4, 3 }, //DatabaseImpl.PARAMETER_SPLIT_PROJECT,
233: { 4, 4 }, //DatabaseImpl.PARAMETER_SPLIT_DEPARTMENT
234: { 5, 2 }, //DatabaseImpl.PARAMETER_MERGE_DEPARTMENT,
235: { 3, 2 }, //DatabaseImpl.PARAMETER_INCREASE_SALARY,
236: { 0, 5 }, //DatabaseImpl.PARAMETER_GET_DEPARTMENT,
237: { 0, 3 }, //DatabaseImpl.PARAMETER_GET_PROJECT,
238: { 0, 1 }, //DatabaseImpl.PARAMETER_GET_EMPLOYEE,
239: { 0, 3 }, //DatabaseImpl.PARAMETER_QUERY_PROJECT,
240: { 0, 2 }, //DatabaseImpl.PARAMETER_QUERY_EMPLOYEE
241: { 0, 0 } //DatabaseImpl.PARAMETER_PING
242: };
243:
244: /**
245: * The Vector <code>poolOfDepartmentId</code> is a static list of known
246: * departmentId used to keep in mind the list of department without doing
247: * any JDO request.
248: * <p>
249: * This is a local cache
250: * </p>
251: */
252: public final static Vector poolOfDepartmentId = new Vector();
253: /**
254: * The Vector <code>poolOfProjectId</code> is a static list of known
255: * projectId used to keep in mind the list of project without doing any JDO
256: * request.
257: * <p>
258: * This is a local cache
259: * </p>
260: */
261: public final static Vector poolOfProjectId = new Vector();
262: /**
263: * The Vector <code>poolOfEmployeeId</code> is a static list of known
264: * employeeId used to keep in mind the list of employee without doing any
265: * JDO request.
266: * <p>
267: * This is a local cache
268: * </p>
269: */
270: public final static Vector poolOfEmployeeId = new Vector();
271:
272: private static boolean resetPools = true;
273:
274: static Logger logger = Monolog.initialize().getLogger(
275: DatabaseImpl.class.getName());
276:
277: private static Hashtable needTransactionArray = new Hashtable();;
278:
279: static {
280: // define the action needing transaction.
281: int writeWeight;
282: for (int i = 0; i < DatabaseImpl.actionWeightArray.length; i++) {
283: writeWeight = DatabaseImpl.actionWeightArray[i][DatabaseImpl.WRITE];
284: needTransactionArray.put(DatabaseImpl.actionArray[i],
285: Boolean.valueOf(writeWeight != 0));
286: }
287: }
288:
289: private final static int PROJECT_INIT_SIZE = 100;
290: private final static int DEPARTMENT_INIT_SIZE = 30;
291:
292: public final static DatabaseImpl instance = new DatabaseImpl();
293:
294: //private PMHolder persistenceManagerHolder;
295: private DepartmentFactory departmentFactory = null;
296: private EmployeeFactory employeeFactory = null;
297: private ProjectFactory projectFactory = null;
298:
299: private DatabaseImpl() {
300: this .departmentFactory = new DepartmentFactory();
301: this .employeeFactory = new EmployeeFactory();
302: this .projectFactory = new ProjectFactory();
303: }
304:
305: /**
306: * This method initialize the action to be performed, enables or disables
307: * transaction management according the parameter withTransaction and calls
308: * the private doAction() method.
309: *
310: * @param parameter
311: * is the action to be performed
312: * @param withTransaction
313: * is a boolean use to enable or disable the use of transaction
314: * @return threatment result as String
315: * @throws JDOException
316: * @throws Exception
317: */
318: public String doAction(String action, boolean performCommit,
319: PMHolder pmHolder) {
320: if (PARAMETER_PING.equalsIgnoreCase(action)) {
321: return "Alive...";
322: }
323: PersistenceManager pm = pmHolder.getPersistenceManager();
324: StringBuffer outStr = new StringBuffer();
325: try {
326: boolean demarcateJDOTx = (performCommit || ((Boolean) needTransactionArray
327: .get(action)).booleanValue())
328: && !pm.currentTransaction().isActive();
329: if (PARAMETER_EVICTALL.equalsIgnoreCase(action)) {
330: logger.log(BasicLevel.INFO, "Flushing cache ...");
331: pm.evictAll();
332: resetPools(pm, outStr);
333: return "Cache flushed !";
334: }
335: initPools(pm);
336: PollsSynchronizations poolsSync = new PollsSynchronizations();
337: pm.setUserObject(poolsSync);
338: pm.currentTransaction().setSynchronization(poolsSync);
339: if (demarcateJDOTx) {
340: logger.log(BasicLevel.INFO, "Begin JDO transaction.");
341: pm.currentTransaction().begin();
342: }
343: StringTokenizer st = new StringTokenizer(action.trim(),
344: ", ", false);
345: while (st.hasMoreTokens()) {
346: doAction(st.nextToken(), poolsSync, outStr, pm);
347: }
348: if (demarcateJDOTx && pm.currentTransaction().isActive()) {
349: logger.log(BasicLevel.INFO, "Commit JDO transaction.");
350: pm.currentTransaction().commit();
351: }
352: } catch (RuntimeException e) {
353: logger.log(BasicLevel.WARN, "The action : '" + action
354: + "' fails : Action canceled.", e);
355: if (!pm.isClosed() && pm.currentTransaction().isActive()) {
356: pm.currentTransaction().rollback();
357: }
358: if (!(e instanceof JDOFatalException)) {
359: outStr.append("Action canceled").append(e.getMessage());
360: } else {
361: throw e;
362: }
363: } finally {
364: pmHolder.closePersistenceManager();
365: }
366: return outStr.toString();
367: }
368:
369: private void doAction(String action,
370: PollsSynchronizations poolsSync, StringBuffer outStr,
371: PersistenceManager pm) {
372: logger.log(BasicLevel.DEBUG, "do action " + action);
373: if (PARAMETER_NEW_DEPARTMENT.equalsIgnoreCase(action)) {
374: departmentFactory.newDepartmentWithEmployees(poolsSync,
375: outStr, pm);
376: } else if (PARAMETER_NEW_PROJECT.equalsIgnoreCase(action)) {
377: projectFactory.newProjectWithEmployees(poolsSync, outStr,
378: pm);
379: } else if (PARAMETER_SET_BOSS.equalsIgnoreCase(action)) {
380: departmentFactory.setManagerForADepartment(outStr, pm);
381: } else if (PARAMETER_NEW_EMPLOYEE.equalsIgnoreCase(action)) {
382: employeeFactory.newEmployee(poolsSync, outStr, pm);
383: } else if (PARAMETER_REM_EMPLOYEE.equalsIgnoreCase(action)) {
384: employeeFactory.deleteEmployee(poolsSync, outStr, pm);
385: } else if (PARAMETER_REM_PROJECT.equalsIgnoreCase(action)) {
386: projectFactory.deleteProject(poolsSync, outStr, pm);
387: } else if (PARAMETER_SPLIT_PROJECT.equalsIgnoreCase(action)) {
388: projectFactory.splitProject(poolsSync, outStr, pm);
389: } else if (PARAMETER_MERGE_DEPARTMENT.equalsIgnoreCase(action)) {
390: departmentFactory.mergeDepartment(poolsSync, outStr, pm);
391: } else if (PARAMETER_SPLIT_DEPARTMENT.equalsIgnoreCase(action)) {
392: departmentFactory.splitDepartment(poolsSync, outStr, pm);
393: } else if (PARAMETER_INCREASE_SALARY.equalsIgnoreCase(action)) {
394: employeeFactory.increaseSalary(outStr, pm);
395: } else if (PARAMETER_GET_DEPARTMENT.equalsIgnoreCase(action)) {
396: departmentFactory.getDepartment(outStr, pm);
397: } else if (PARAMETER_GET_PROJECT.equalsIgnoreCase(action)) {
398: projectFactory.getProject(outStr, pm);
399: } else if (PARAMETER_GET_EMPLOYEE.equalsIgnoreCase(action)) {
400: employeeFactory.getEmployee(outStr, pm);
401: } else if (PARAMETER_QUERY_PROJECTS.equalsIgnoreCase(action)) {
402: projectFactory.getProjects(outStr, pm);
403: } else if (PARAMETER_QUERY_EMPLOYEES.equalsIgnoreCase(action)) {
404: employeeFactory.getEmployees(outStr, pm);
405: } else {
406: resetPools(pm, outStr);
407: }
408: logger.log(BasicLevel.DEBUG, "End of action : " + action);
409: }
410:
411: private synchronized static void resetPools(PersistenceManager pm,
412: StringBuffer outStr) {
413: logger.log(BasicLevel.DEBUG, "Resets and shows pools");
414: poolOfDepartmentId.clear();
415: poolOfEmployeeId.clear();
416: poolOfProjectId.clear();
417: resetPools = true;
418: initPools(pm);
419: if (outStr != null) {
420: outStr.append("\nDo nothing and dump static poll contents");
421: outStr.append("\nDepartments:");
422: outStr.append(DatabaseImpl.poolOfDepartmentId.toString());
423: outStr.append("\nEmployees:");
424: outStr.append(DatabaseImpl.poolOfEmployeeId.toString());
425: outStr.append("\nProjects:");
426: outStr.append(DatabaseImpl.poolOfProjectId.toString());
427: }
428: }
429:
430: private static synchronized void initPools(PersistenceManager pm) {
431: if (!resetPools) {
432: return;
433: }
434: try {
435: if (poolOfDepartmentId.isEmpty()) {
436: initPool(poolOfDepartmentId, Department.class, pm);
437: logger.log(BasicLevel.DEBUG,
438: "Initialize the static pool of Departments Id : "
439: + poolOfDepartmentId);
440: }
441: if (poolOfProjectId.isEmpty()) {
442: initPool(poolOfProjectId, Project.class, pm);
443: logger.log(BasicLevel.DEBUG,
444: "Initialize the static pool of Projects Id : "
445: + poolOfProjectId);
446: }
447: if (poolOfEmployeeId.isEmpty()) {
448: initPool(poolOfEmployeeId, Employee.class, pm);
449: logger.log(BasicLevel.DEBUG,
450: "Initialize the static pool of Employees Id : "
451: + poolOfEmployeeId);
452: }
453: } finally {
454: DatabaseImpl.resetPools = false;
455: }
456: }
457:
458: /**
459: * Initializes a pool of identifier
460: * @param pool is the pool to fill
461: * @param c is the persistent class
462: * @param pm is the persistence manager to use
463: */
464: private static void initPool(Collection pool, Class c,
465: PersistenceManager pm) {
466: logger.log(BasicLevel.INFO,
467: "(Re)Initialize static pool id for classe : "
468: + c.getName());
469: pm.getObjectIdClass(c);
470: boolean hasMoreResult = true;
471: int idx = 0;
472: final int page_size = 1000;
473: boolean hasTx = pm.currentTransaction().isActive();
474: if (hasTx) {
475: pm.currentTransaction().commit();
476: }
477: while (hasMoreResult) {
478: pm.currentTransaction().begin();
479: Query query = pm.newQuery(c);
480: query.setRange(idx, idx + page_size);
481: int nb = 0;
482: try {
483: Collection col = (Collection) query.execute();
484: for (Iterator it = col.iterator(); it.hasNext();) {
485: nb++;
486: pool.add(new Long(((DatabaseObjectInterface) it
487: .next()).getId()));
488: }
489: } finally {
490: query.closeAll();
491: }
492: idx += page_size;
493: hasMoreResult = nb > 0;
494: pm.currentTransaction().commit();
495: }
496: }
497:
498: /**
499: * Gets an element from the pool.
500: */
501: private final static long getIdFromPool(Vector pool) {
502: // Get an id from the pool.
503: while (DatabaseImpl.resetPools) {
504: try {
505: logger
506: .log(BasicLevel.DEBUG,
507: "sleep until the end off static pool id reset...");
508: Thread.sleep(10);
509: } catch (InterruptedException e) {
510: }
511: }
512: int alea = Alea.rand(0, Math.max(0, pool.size() - 1));
513: synchronized (pool) {
514: return ((Long) pool.get(alea)).longValue();
515: }
516: }
517:
518: public static void initTestData(PMHolder pmHolder)
519: throws JDOException, Exception {
520: String str;
521: PersistenceManager pm = pmHolder.getPersistenceManager();
522: pm.evictAll();
523: Iterator objIter = null;
524: DatabaseImpl.poolOfDepartmentId.clear();
525: DatabaseImpl.poolOfEmployeeId.clear();
526: DatabaseImpl.poolOfProjectId.clear();
527: // remove all employee
528: Class[] classes = new Class[] { Employee.class, Address.class,
529: Project.class, Department.class };
530: pm.currentTransaction().begin();
531: for (int i = 0; i < classes.length; i++) {
532: logger.log(BasicLevel.DEBUG, "Removing "
533: + classes[i].getName() + " ...");
534: pm.deletePersistentAll((Collection) pm.newQuery(classes[i])
535: .execute());
536: logger.log(BasicLevel.INFO, "All " + classes[i].getName()
537: + " have been removed.");
538: }
539: pm.currentTransaction().commit();
540:
541: pm.evictAll();
542:
543: pm.currentTransaction().begin();
544: logger.log(BasicLevel.INFO,
545: "Init departments and employees data.");
546: for (int i = 0; i < DEPARTMENT_INIT_SIZE; i++) {
547: str = DatabaseImpl.instance.doAction(
548: PARAMETER_NEW_DEPARTMENT, false, pmHolder);
549: logger.log(BasicLevel.DEBUG, str);
550: }
551: DatabaseImpl.resetPools = true;
552: logger.log(BasicLevel.INFO, "Init projects data.");
553: for (int i = 0; i < PROJECT_INIT_SIZE; i++) {
554: str = DatabaseImpl.instance.doAction(PARAMETER_NEW_PROJECT,
555: false, pmHolder);
556: logger.log(BasicLevel.DEBUG, str);
557: }
558: DatabaseImpl.resetPools = true;
559: pm.currentTransaction().commit();
560: logger.log(BasicLevel.INFO, "Initial data set.");
561: resetPools(pm, null);
562: pm.evictAll();
563: logger.log(BasicLevel.DEBUG, "Remove all cache entries.");
564: pmHolder.closePersistenceManager();
565: logger.log(BasicLevel.DEBUG, "Close the persistenceManager.");
566: }
567:
568: /**
569: * Returns one of the existing department id
570: *
571: * @return a department id
572: */
573: public static long getDepartmentIdFromPool() {
574: return DatabaseImpl
575: .getIdFromPool(DatabaseImpl.poolOfDepartmentId);
576: }
577:
578: /**
579: * Returns one of the existing employee id
580: *
581: * @return a employee id
582: */
583: public static long getEmployeeIdFromPool() {
584: return DatabaseImpl
585: .getIdFromPool(DatabaseImpl.poolOfEmployeeId);
586: }
587:
588: /**
589: * Returns one of the existing project id
590: *
591: * @return a project id
592: */
593: public static long getProjectIdFromPool() {
594: return DatabaseImpl.getIdFromPool(DatabaseImpl.poolOfProjectId);
595: }
596: }
|