001/* An attribute that replaces any previous instance with the same name. 002 003 Copyright (c) 1998-2014 The Regents of the University of California. 004 All rights reserved. 005 Permission is hereby granted, without written agreement and without 006 license or royalty fees, to use, copy, modify, and distribute this 007 software and its documentation for any purpose, provided that the above 008 copyright notice and the following two paragraphs appear in all copies 009 of this software. 010 011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 015 SUCH DAMAGE. 016 017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 022 ENHANCEMENTS, OR MODIFICATIONS. 023 024 PT_COPYRIGHT_VERSION_2 025 COPYRIGHTENDKEY 026 027 */ 028package ptolemy.kernel.util; 029 030/////////////////////////////////////////////////////////////////// 031//// SingletonAttribute 032 033/** 034 This class is an attribute that replaces any previously 035 existing attribute in the container that has the same name. 036 037 @author Steve Neuendorffer and Edward A. Lee 038 @version $Id$ 039 @since Ptolemy II 1.0 040 @Pt.ProposedRating Green (eal) 041 @Pt.AcceptedRating Green (janneck) 042 */ 043public class SingletonAttribute extends Attribute implements Singleton { 044 /** Construct a new attribute with no 045 * container and an empty string as its name. Add the attribute to the 046 * workspace directory. 047 * Increment the version number of the workspace. 048 */ 049 public SingletonAttribute() { 050 super(); 051 } 052 053 /** Construct a new attribute with 054 * no container and an empty string as a name. You can then change 055 * the name with setName(). If the workspace argument is null, then 056 * use the default workspace. 057 * Add the attribute to the workspace directory. 058 * Increment the version number of the workspace. 059 * @param workspace The workspace that will list the attribute. 060 */ 061 public SingletonAttribute(Workspace workspace) { 062 super(workspace); 063 } 064 065 /** Construct an attribute with the given container and name. 066 * If an attribute already exists with the same name as the one 067 * specified here, that is an instance of class 068 * SingletonAttribute (or a derived class), then that 069 * attribute is removed before this one is inserted in the container. 070 * @param container The container. 071 * @param name The name of this attribute. 072 * @exception IllegalActionException If the attribute cannot be contained 073 * by the proposed container. 074 * @exception NameDuplicationException If the container already has an 075 * attribute with this name, and the class of that container is not 076 * SingletonAttribute. 077 */ 078 public SingletonAttribute(NamedObj container, String name) 079 throws NameDuplicationException, IllegalActionException { 080 super(container, name); 081 } 082 083 /////////////////////////////////////////////////////////////////// 084 //// public methods //// 085 086 /** Remove any previous attribute in the container that has the same 087 * name as this attribute, and then call the base class method to set 088 * the container. If the container is not in the same workspace as 089 * this attribute, throw an exception. 090 * If this attribute is already contained by the NamedObj, do nothing. 091 * If the attribute already has a container, remove 092 * this attribute from its attribute list first. Otherwise, remove 093 * it from the directory of the workspace, if it is there. 094 * If the argument is null, then remove this attribute from its 095 * container. It is not added to the workspace directory, so this 096 * could result in this object being garbage collected. 097 * <p> 098 * Note that since an Attribute is a NamedObj, it can itself have 099 * attributes. However, recursive containment is not allowed, where 100 * an attribute is an attribute of itself, or indirectly of any attribute 101 * it contains. 102 * <p> 103 * This method is write-synchronized on the 104 * workspace and increments its version number. 105 * @param container The container to attach this attribute to. 106 * @exception IllegalActionException If this attribute is not of the 107 * expected class for the container, or it has no name, 108 * or the attribute and container are not in the same workspace, or 109 * the proposed container would result in recursive containment. 110 * @exception NameDuplicationException If the container already has 111 * an attribute with the name of this attribute that is of class 112 * SingletonConfigurableAttribute. 113 */ 114 @Override 115 public void setContainer(NamedObj container) 116 throws IllegalActionException, NameDuplicationException { 117 Attribute previous = null; 118 119 if (container != null) { 120 previous = container.getAttribute(getName()); 121 122 if (previous != null) { 123 previous.setContainer(null); 124 } 125 } 126 127 try { 128 super.setContainer(container); 129 } catch (IllegalActionException ex) { 130 // Restore previous. 131 if (previous != null) { 132 previous.setContainer(container); 133 } 134 135 throw ex; 136 } catch (NameDuplicationException ex) { 137 // Restore previous. 138 if (previous != null) { 139 previous.setContainer(container); 140 } 141 142 throw ex; 143 } 144 } 145}