001: /*
002: The contents of this file are subject to the Common Public Attribution License
003: Version 1.0 (the "License"); you may not use this file except in compliance with
004: the License. You may obtain a copy of the License at
005: http://www.projity.com/license . The License is based on the Mozilla Public
006: License Version 1.1 but Sections 14 and 15 have been added to cover use of
007: software over a computer network and provide for limited attribution for the
008: Original Developer. In addition, Exhibit A has been modified to be consistent
009: with Exhibit B.
010:
011: Software distributed under the License is distributed on an "AS IS" basis,
012: WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
013: specific language governing rights and limitations under the License. The
014: Original Code is OpenProj. The Original Developer is the Initial Developer and
015: is Projity, Inc. All portions of the code written by Projity are Copyright (c)
016: 2006, 2007. All Rights Reserved. Contributors Projity, Inc.
017:
018: Alternatively, the contents of this file may be used under the terms of the
019: Projity End-User License Agreeement (the Projity License), in which case the
020: provisions of the Projity License are applicable instead of those above. If you
021: wish to allow use of your version of this file only under the terms of the
022: Projity License and not to allow others to use your version of this file under
023: the CPAL, indicate your decision by deleting the provisions above and replace
024: them with the notice and other provisions required by the Projity License. If
025: you do not delete the provisions above, a recipient may use your version of this
026: file under either the CPAL or the Projity License.
027:
028: [NOTE: The text of this license may differ slightly from the text of the notices
029: in Exhibits A and B of the license at http://www.projity.com/license. You should
030: use the latest text at http://www.projity.com/license for your modifications.
031: You may not remove this license text from the source files.]
032:
033: Attribution Information: Attribution Copyright Notice: Copyright � 2006, 2007
034: Projity, Inc. Attribution Phrase (not exceeding 10 words): Powered by OpenProj,
035: an open source solution from Projity. Attribution URL: http://www.projity.com
036: Graphic Image as provided in the Covered Code as file: openproj_logo.png with
037: alternatives listed on http://www.projity.com/logo
038:
039: Display of Attribution Information is required in Larger Works which are defined
040: in the CPAL as a work which combines Covered Code or portions thereof with code
041: not governed by the terms of the CPAL. However, in addition to the other notice
042: obligations, all copies of the Covered Code in Executable and Source Code form
043: distributed must, as a form of attribution of the original author, include on
044: each user interface screen the "OpenProj" logo visible to all users. The
045: OpenProj logo should be located horizontally aligned with the menu bar and left
046: justified on the top left of the screen adjacent to the File menu. The logo
047: must be at least 100 x 25 pixels. When users click on the "OpenProj" logo it
048: must direct them back to http://www.projity.com.
049: */
050: package com.projity.pm.resource;
051:
052: import java.util.ArrayList;
053: import java.util.HashMap;
054: import java.util.Iterator;
055: import java.util.List;
056:
057: import com.projity.configuration.Settings;
058: import com.projity.document.Document;
059: import com.projity.document.ObjectEvent;
060: import com.projity.document.ObjectEventManager;
061: import com.projity.grouping.core.Node;
062: import com.projity.grouping.core.NodeList;
063: import com.projity.grouping.core.OutlineCollection;
064: import com.projity.grouping.core.OutlineCollectionImpl;
065: import com.projity.grouping.core.model.AssignmentNodeModel;
066: import com.projity.grouping.core.model.NodeModel;
067: import com.projity.grouping.core.model.NodeModelDataFactory;
068: import com.projity.pm.calendar.CalendarService;
069: import com.projity.pm.calendar.WorkCalendar;
070: import com.projity.pm.calendar.WorkingCalendar;
071: import com.projity.pm.task.Project;
072: import com.projity.undo.DataFactoryUndoController;
073:
074: /**
075: *
076: */
077: public class ResourcePool implements Document, NodeModelDataFactory {
078: private String name = "";
079: private ArrayList resourceList = new ArrayList();
080: private ArrayList projects = new ArrayList();
081: private ObjectEventManager objectEventManager = new ObjectEventManager();
082: private int resourceIdCounter = 0;
083: private WorkingCalendar defaultCalendar;
084: private static ResourcePool globalPool = null; // TODO is it ok to be global?
085:
086: protected ResourcePool(String name, DataFactoryUndoController undo) {
087: this .name = name;
088: globalPool = this ;
089: defaultCalendar = CalendarService.getInstance()
090: .getDefaultInstance();
091: undoController = undo;
092:
093: //initUndo();
094: }
095:
096: public static ResourcePool createRourcePool(String name,
097: DataFactoryUndoController undo) {
098: ResourcePool pool = new ResourcePool(name, undo);
099: pool.initializeOutlines();
100: return pool;
101: }
102:
103: private transient HashMap<Long, Resource> idMap = null;
104:
105: public Resource findById(long id) {
106: if (idMap == null) {
107: idMap = new HashMap<Long, Resource>();
108: Iterator i = getResourceList().iterator();
109: Resource resource;
110: while (i.hasNext()) {
111: resource = (Resource) i.next();
112: idMap.put(resource.getUniqueId(), resource);
113: }
114: }
115: return idMap.get(id);
116: }
117:
118: public void initializeId(Resource resource) {
119: long id = ++resourceIdCounter;
120: resource.setId(id); //starts at 1TODO check for duplicates -
121: //resource.setUniqueId(id); //TODO use a GUID generator
122: }
123:
124: public void initializeOutlines() {
125: int count = Settings.numHierarchies();
126: for (int i = 0; i < count; i++) {
127: NodeModel model = resourceOutlines.getOutline(i);
128: if (model == null)
129: continue;
130: if (model instanceof AssignmentNodeModel) {
131: AssignmentNodeModel aModel = (AssignmentNodeModel) model;
132: aModel.setDocument(this );
133: }
134: initOutline(model);
135: }
136: }
137:
138: public void addAndInitializeId(Resource resource) {
139: add(resource);
140: initializeId(resource);
141: }
142:
143: public void add(Resource resource) {
144: resourceList.add(resource);
145: }
146:
147: public void remove(Resource resource) {
148: resourceList.remove(resource);
149: }
150:
151: public ResourceImpl newResourceInstance() {
152: EnterpriseResource globalResource = new EnterpriseResource(
153: isLocal(), this );
154: ResourceImpl newOne = new ResourceImpl(globalResource);
155:
156: addAndInitializeId(newOne);
157: return newOne;
158: }
159:
160: public Resource createScriptedResource() {
161: Resource res = newResourceInstance();
162: resourceOutlines.addToAll(res, null); // update all node models
163: return res;
164: }
165:
166: /**
167: * @return Returns the resourceList.
168: */
169: public ArrayList getResourceList() {
170: return resourceList;
171: }
172:
173: public static Resource findResourceByName(Object idObject,
174: Object resourcePoolObject) {
175: Iterator i = ((ResourcePool) resourcePoolObject)
176: .getResourceList().iterator();
177: String id = (String) idObject;
178: Resource resource;
179: while (i.hasNext()) {
180: resource = (Resource) i.next();
181: if (resource.getName().equals(id))
182: return resource;
183: }
184: return null;
185: }
186:
187: public static Resource findResourceByInitials(Object idObject,
188: Object resourcePoolObject) {
189: Iterator i = ((ResourcePool) resourcePoolObject)
190: .getResourceList().iterator();
191: int id = ((Integer) idObject).intValue();
192: Resource resource;
193: while (i.hasNext()) {
194: resource = (Resource) i.next();
195: if (resource.getId() == id)
196: return resource;
197: }
198: return null;
199: }
200:
201: private OutlineCollection resourceOutlines = new OutlineCollectionImpl(
202: Settings.numHierarchies(), this );
203:
204: public NodeModel getResourceOutline() {
205: NodeModel model = resourceOutlines.getOutline();
206: return model;
207: }
208:
209: public NodeModel getResourceOutline(int outlineNumber) {
210: NodeModel model = resourceOutlines.getOutline(outlineNumber);
211: return model;
212: }
213:
214: public void addToDefaultOutline(Node parentNode, Node childNode) {
215: resourceOutlines.addToDefaultOutline(parentNode, childNode);
216: }
217:
218: public void addToDefaultOutline(Node parentNode, Node childNode,
219: int position, boolean event) {
220: resourceOutlines.addToDefaultOutline(parentNode, childNode,
221: position, event);
222: }
223:
224: /* (non-Javadoc)
225: * @see com.projity.grouping.core.NodeModelDataFactory#createUnvalidatedObject(com.projity.grouping.core.NodeModel)
226: */
227: public Object createUnvalidatedObject(NodeModel nodeModel,
228: Object parent) {
229: EnterpriseResource globalResource = new EnterpriseResource(
230: isLocal(), this );
231: ResourceImpl newOne = new ResourceImpl(globalResource);
232: newOne.getGlobalResource().setMaster(isMaster());
233: newOne.getGlobalResource().setLocal(isLocal());
234: addUnvalidatedObject(newOne, nodeModel, parent);
235: return newOne;
236: }
237:
238: public void addUnvalidatedObject(Object object,
239: NodeModel nodeModel, Object parent) {
240: }
241:
242: /* (non-Javadoc)
243: * @see com.projity.grouping.core.NodeModelDataFactory#validateObject(java.lang.Object, com.projity.grouping.core.NodeModel)
244: */
245: public void validateObject(Object newlyCreated,
246: NodeModel nodeModel, Object eventSource,
247: Object hierarchyInfo, boolean isNew) {
248: if (!(newlyCreated instanceof Resource))
249: return;// avoids VoidNodes
250: Resource resource = (Resource) newlyCreated;
251:
252: ((ResourceImpl) resource).getGlobalResource().setResourcePool(
253: this );
254:
255: add(resource);
256: if (isNew)
257: initializeId(resource);
258: resourceOutlines.addToAll(newlyCreated, nodeModel); // update all node models except the one passed in
259: //objectEventManager.fireCreateEvent(this,newlyCreated);
260: }
261:
262: // public void fireCreated(Object newlyCreated){
263: // //objectEventManager.fireCreateEvent(this,newlyCreated);
264: // }
265: /* (non-Javadoc)
266: * @see com.projity.grouping.core.NodeModelDataFactory#remove(java.lang.Object)
267: */
268: public void remove(Object toRemove, NodeModel nodeModel,
269: boolean deep, boolean undo, boolean removeDependencies) {
270: remove((Resource) toRemove);
271: resourceOutlines.removeFromAll(toRemove, nodeModel); // update all node models except the one passed in
272: }
273:
274: public void addProject(Project project) {
275: projects.add(project);
276: // initUndoControlerForAllOutines(project);
277: }
278:
279: public void removeProject(Project project) {
280: projects.remove(project);
281: }
282:
283: /**
284: * @return Returns the projects.
285: */
286: public ArrayList getProjects() {
287: return projects;
288: }
289:
290: /**
291: * @param listener
292: */
293: public void addObjectListener(ObjectEvent.Listener listener) {
294: objectEventManager.addListener(listener);
295: }
296:
297: /**
298: * @param listener
299: */
300: public void removeObjectListener(ObjectEvent.Listener listener) {
301: objectEventManager.removeListener(listener);
302: }
303:
304: public ObjectEventManager getObjectEventManager() {
305: return objectEventManager;
306: }
307:
308: public void fireUpdateEvent(Object source, Object object) {
309: objectEventManager.fireUpdateEvent(source, object);
310: }
311:
312: public String toString() {
313: return name;
314: }
315:
316: /**
317: * @return Returns the name.
318: */
319: public String getName() {
320: return name;
321: }
322:
323: /**
324: * @param name The name to set.
325: */
326: public void setName(String name) {
327: this .name = name;
328: }
329:
330: /* (non-Javadoc)
331: * @see com.projity.document.Document#fireMultipleTransaction(int, boolean)
332: */
333: public int fireMultipleTransaction(int id, boolean begin) {
334: // TODO Auto-generated method stub
335: return 0;
336: }
337:
338: /**
339: * @return Returns the defaultCalendar.
340: */
341: public final WorkCalendar getDefaultCalendar() {
342: return defaultCalendar;
343: }
344:
345: public ArrayList extractCalendars() {
346: return WorkingCalendar.extractCalendars(resourceList);
347: }
348:
349: private transient boolean isDirty = false;
350:
351: public final boolean isGroupDirty() {
352: // for (Iterator i=getProjects().iterator();i.hasNext();){
353: // Project project=(Project)i.next();
354: // if (project.isGroupDirty()) return true;
355: // }
356: // return false;
357: return isDirty;
358: }
359:
360: public final void setGroupDirty(boolean isDirty) {
361: System.out.println("ResourcePool.setGroupDirty(" + isDirty
362: + ")");
363: this .isDirty = isDirty;
364: if (isDirty)
365: for (Iterator i = getProjects().iterator(); i.hasNext();) {
366: Project project = (Project) i.next();
367: project.setGroupDirty(true);
368: }
369: }
370:
371: protected boolean master;
372:
373: public boolean isMaster() {
374: return master;
375: }
376:
377: public void setMaster(boolean master) {
378: this .master = master;
379: }
380:
381: protected boolean local;
382:
383: public boolean isLocal() {
384: return local;
385: }
386:
387: public void setLocal(boolean local) {
388: this .local = local;
389: }
390:
391: public void updateOutlineTypes() {
392: NodeModel[] models = resourceOutlines.getOutlines();
393: for (int i = 0; i < models.length; i++) {
394: initOutline(models[i]);
395: }
396: }
397:
398: public void initOutline(NodeModel nodeModel) {
399: if (nodeModel != null) {
400: nodeModel.setLocal(local);
401: nodeModel.setMaster(master);
402: }
403: }
404:
405: //Undo
406: protected transient DataFactoryUndoController undoController;
407:
408: // protected void initUndo(){
409: // undoController=new DataFactoryUndoController(this);
410: // }
411: public DataFactoryUndoController getUndoController() {
412: return undoController;
413: }
414:
415: public void setUndoController(
416: DataFactoryUndoController undoController) {
417: this .undoController = undoController;
418: }
419:
420: public void rollbackUnvalidated(NodeModel nodeModel, Object object) {
421: }
422:
423: public NodeModelDataFactory getFactoryToUseForChildOfParent(
424: Object impl) {
425: return this ;
426: }
427:
428: public void setAllChildrenDirty(boolean dirty) {
429: }
430:
431: public boolean containsAssignments() {
432: return true;
433: }
434:
435: public static final Object[] userResources() {
436: Iterator i = globalPool.getResourceList().iterator();
437: Resource resource;
438: ArrayList result = new ArrayList();
439: while (i.hasNext()) {
440: resource = (Resource) i.next();
441: if (resource.isUser())
442: result.add(resource);
443: }
444: return result.toArray();
445: }
446:
447: public static final Resource findResource(String name) {
448: return findResourceByName(name, globalPool);
449: }
450:
451: public List getChildrenResoures(Resource parent) {
452: NodeModel resourceModel = getResourceOutline();
453: Node node = resourceModel.search(parent);
454: return NodeList.nodeListToImplList(resourceModel
455: .getChildren(node));
456: }
457:
458: public Resource getRbsParentResource(Resource child) {
459: NodeModel resourceModel = getResourceOutline();
460: Node node = resourceModel.search(child);
461: Node parent = resourceModel.getParent(node);
462: if (parent == null || parent.isVoid())
463: return null;
464: return (Resource) parent.getImpl();
465: }
466:
467: public void setLocalParent(Resource child, Resource parent) {
468: Node childNode = getResourceOutline().search(child);
469: Node parentNode = parent == null ? null : getResourceOutline()
470: .search(parent);
471: setLocalParent(childNode, parentNode);
472: }
473:
474: public void setLocalParent(Node childNode, Node parentNode) {
475: Resource child = (Resource) childNode.getImpl();
476: Resource parent = (Resource) (parentNode == null ? null
477: : parentNode.getImpl());
478: if (getRbsParentResource(child) == parent)
479: return;
480: Node oldParentNode = getResourceOutline().search(
481: getRbsParentResource(child));
482: if (oldParentNode != null)
483: oldParentNode.getChildren().remove(childNode);
484: ArrayList temp = new ArrayList();
485: temp.add(childNode);
486: getResourceOutline().move(parentNode, temp, -1,
487: NodeModel.NORMAL);
488: }
489: }
|