/* $Id: MemberList.java 17822 2010-01-12 18:47:46Z linus $ ***************************************************************************** * Copyright (c) 2009 Contributors - see below * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * tfmorris ***************************************************************************** * * Some portions of this file was previously release using the BSD License: */ // Copyright (c) 2004-2008 The Regents of the University of California. All // Rights Reserved. Permission to use, copy, modify, and distribute this // software and its documentation without fee, and without a written // agreement is hereby granted, provided that the above copyright notice // and this paragraph appear in all copies. This software program and // documentation are copyrighted by The Regents of the University of // California. The software program and documentation are supplied "AS // IS", without any accompanying services from The Regents. The Regents // does not warrant that the operation of the program will be // uninterrupted or error-free. The end-user understands that the program // was developed for research purposes and is advised not to rely // exclusively on the program for any reason. IN NO EVENT SHALL THE // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, // UPDATES, ENHANCEMENTS, OR MODIFICATIONS. package org.argouml.kernel; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import org.apache.log4j.Logger; import org.argouml.uml.ProjectMemberModel; import org.argouml.uml.cognitive.ProjectMemberTodoList; import org.argouml.uml.diagram.ArgoDiagram; import org.argouml.uml.diagram.ProjectMemberDiagram; /** * List of ProjectMembers. <p> * * <p>The project members are grouped into 4 categories: * model, diagrams, the todo item list and the profile configuration. <p> * * <p>The purpose of these categories is to make sure that members are read * and written in the correct order. * * <p>When reading the todo items it will fail if the diagrams elements or model * elements have not yet been read that they refer to. When reading diagrams * that will fail if the model elements don't yet exist that they refer to. * When loading the model that may fail if the correct profile has not been * loaded. * * <p>Hence, the save (and therefore load) order is profile, model, diagrams, * todo items. * * <p>This implementation supports only one profile configuration, one model * member, multiple diagram members, one todo list member. * * <p>Comments by mvw: <p> * This class should be reworked to be independent * of the org.argouml.uml package. That can be done by extending the * ProjectMember interface with functions returning the sorting order, * and if multiple entries of the same type are allowed. <p> * * In preparation, this class is made simpler by deprecating * all operations that are not part of the List interface. * * @author Bob Tarling */ class MemberList implements List<ProjectMember> { /** * Logger. */ private static final Logger LOG = Logger.getLogger(MemberList.class); private AbstractProjectMember model; private List<ProjectMemberDiagram> diagramMembers = new ArrayList<ProjectMemberDiagram>(10); private AbstractProjectMember todoList; private AbstractProjectMember profileConfiguration; /** * The constructor. */ public MemberList() { LOG.info("Creating a member list"); } public synchronized boolean add(ProjectMember member) { if (member instanceof ProjectMemberModel) { // Always put the model at the top model = (AbstractProjectMember) member; return true; } else if (member instanceof ProjectMemberTodoList) { // otherwise add the diagram at the start setTodoList((AbstractProjectMember) member); return true; } else if (member instanceof ProfileConfiguration) { profileConfiguration = (AbstractProjectMember) member; return true; } else if (member instanceof ProjectMemberDiagram) { // otherwise add the diagram at the start return diagramMembers.add((ProjectMemberDiagram) member); } return false; } public synchronized boolean remove(Object member) { LOG.info("Removing a member"); if (member instanceof ArgoDiagram) { return removeDiagram((ArgoDiagram) member); } ((AbstractProjectMember) member).remove(); if (model == member) { model = null; return true; } else if (todoList == member) { LOG.info("Removing todo list"); setTodoList(null); return true; } else if (profileConfiguration == member) { LOG.info("Removing profile configuration"); profileConfiguration = null; return true; } else { final boolean removed = diagramMembers.remove(member); if (!removed) { LOG.warn("Failed to remove diagram member " + member); } return removed; } } public synchronized Iterator<ProjectMember> iterator() { return buildOrderedMemberList().iterator(); } public synchronized ListIterator<ProjectMember> listIterator() { return buildOrderedMemberList().listIterator(); } public synchronized ListIterator<ProjectMember> listIterator(int arg0) { return buildOrderedMemberList().listIterator(arg0); } /** * @return the list of members in the order that they need to be written * out in. */ private List<ProjectMember> buildOrderedMemberList() { List<ProjectMember> temp = new ArrayList<ProjectMember>(size()); if (profileConfiguration != null) { temp.add(profileConfiguration); } if (model != null) { temp.add(model); } temp.addAll(diagramMembers); if (todoList != null) { temp.add(todoList); } return temp; } private boolean removeDiagram(ArgoDiagram d) { for (ProjectMemberDiagram pmd : diagramMembers) { if (pmd.getDiagram() == d) { pmd.remove(); diagramMembers.remove(pmd); return true; } } LOG.debug("Failed to remove diagram " + d); return false; } public synchronized int size() { int size = diagramMembers.size(); if (model != null) { ++size; } if (todoList != null) { ++size; } if (profileConfiguration != null) { ++size; } return size; } public synchronized boolean contains(Object member) { if (todoList == member) { return true; } if (model == member) { return true; } if (profileConfiguration == member) { return true; } return diagramMembers.contains(member); } public synchronized void clear() { LOG.info("Clearing members"); if (model != null) { model.remove(); } if (todoList != null) { todoList.remove(); } if (profileConfiguration != null) { profileConfiguration.remove(); } Iterator membersIt = diagramMembers.iterator(); while (membersIt.hasNext()) { ((AbstractProjectMember) membersIt.next()).remove(); } diagramMembers.clear(); } public synchronized ProjectMember get(int i) { if (model != null) { if (i == 0) { return model; } --i; } if (i == diagramMembers.size()) { if (todoList != null) { return todoList; } else { return profileConfiguration; } } if (i == (diagramMembers.size() + 1)) { return profileConfiguration; } return diagramMembers.get(i); } public synchronized boolean isEmpty() { return size() == 0; } public synchronized ProjectMember[] toArray() { ProjectMember[] temp = new ProjectMember[size()]; int pos = 0; if (model != null) { temp[pos++] = model; } for (ProjectMemberDiagram d : diagramMembers) { temp[pos++] = d; } if (todoList != null) { temp[pos++] = todoList; } if (profileConfiguration != null) { temp[pos++] = profileConfiguration; } return temp; } private void setTodoList(AbstractProjectMember member) { LOG.info("Setting todoList to " + member); todoList = member; } public <T> T[] toArray(T[] a) { throw new UnsupportedOperationException(); } public boolean containsAll(Collection< ? > arg0) { throw new UnsupportedOperationException(); } public boolean addAll(Collection< ? extends ProjectMember> arg0) { throw new UnsupportedOperationException(); } public boolean addAll(int arg0, Collection< ? extends ProjectMember> arg1) { throw new UnsupportedOperationException(); } public boolean removeAll(Collection< ? > arg0) { throw new UnsupportedOperationException(); } public boolean retainAll(Collection< ? > arg0) { throw new UnsupportedOperationException(); } public ProjectMember set(int arg0, ProjectMember arg1) { throw new UnsupportedOperationException(); } public void add(int arg0, ProjectMember arg1) { throw new UnsupportedOperationException(); } public ProjectMember remove(int arg0) { throw new UnsupportedOperationException(); } public int indexOf(Object arg0) { throw new UnsupportedOperationException(); } public int lastIndexOf(Object arg0) { throw new UnsupportedOperationException(); } public List<ProjectMember> subList(int arg0, int arg1) { throw new UnsupportedOperationException(); } }