001/*
002 * Copyright (c) 2010 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: aschultz $'
006 * '$Date: 2011-01-05 07:59:36 +0000 (Wed, 05 Jan 2011) $' 
007 * '$Revision: 26633 $'
008 * 
009 * Permission is hereby granted, without written agreement and without
010 * license or royalty fees, to use, copy, modify, and distribute this
011 * software and its documentation for any purpose, provided that the above
012 * copyright notice and the following two paragraphs appear in all copies
013 * of this software.
014 *
015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
019 * SUCH DAMAGE.
020 *
021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
026 * ENHANCEMENTS, OR MODIFICATIONS.
027 *
028 */
029
030package org.kepler.util;
031
032import java.util.regex.Matcher;
033import java.util.regex.Pattern;
034
035import org.kepler.moml.NamedObjId;
036import org.kepler.objectmanager.lsid.KeplerLSID;
037import org.kepler.objectmanager.lsid.LSIDGenerator;
038
039import ptolemy.actor.gui.Configuration;
040import ptolemy.actor.gui.Effigy;
041import ptolemy.kernel.ComponentEntity;
042import ptolemy.kernel.util.NamedObj;
043import ptolemy.kernel.util.StringAttribute;
044import ptolemy.moml.MoMLChangeRequest;
045import ptolemy.util.StringUtilities;
046
047/**
048 * A utility class for renaming things.
049 * 
050 * @author Aaron Schultz
051 */
052public class RenameUtil {
053
054    /** Regular expression pattern of Unnamed effigy ids. */
055    public static Pattern unnamedIdPattern = Pattern.compile("^Unnamed\\d+$");
056        
057        /**
058         * A method for renaming ComponentEntities. This algorithm is loosely based
059         * on ptolemy.actor.gui.RenameConfigurer.apply() method.
060         * 
061         * @param no
062         * @param newName
063         */
064        public static void renameComponentEntity(ComponentEntity ce, String newName)
065                        throws Exception {
066
067                KeplerLSID origLSID = NamedObjId.getIdFor(ce);
068                String oldName = ce.getName();
069                String displayName = StringUtilities.escapeForXML(newName);
070                NamedObj parent = ce.getContainer();
071                
072                if (parent == null) {
073                        if (!ce.getName().equals(newName)) {
074                                
075                    Matcher matcher = unnamedIdPattern.matcher(ce.getName());
076                                
077                                // Since MoMLChangeRequest requires a parent container
078                                // we'll just set it directly if it doesn't have one
079                                ce.setName(newName);
080                                ce.setDisplayName(displayName);
081
082                                // assign new LSID to workflow except if it's unnamed.
083                    if (!matcher.matches()) {
084                        KeplerLSID newLSID = LSIDGenerator.getInstance().getNewLSID();
085                        NamedObjId.assignIdTo(ce, newLSID, true);
086                        //now we must explicitly requestNamedObjIdChange
087                        NamedObjId.getIdAttributeFor(ce).requestNamedObjIdChange();
088                    }
089                    else{
090                        // if unnamed, just updateRevision.
091                        NamedObjId.getIdAttributeFor(ce).updateRevision();
092                    }
093                        }
094                        KeplerLSID currentLSID = NamedObjId.getIdFor(ce);
095                        notifyWorkflowRenameListeners(ce, oldName, newName, origLSID, currentLSID);
096                        
097                        // fixes bug 5101
098                        Effigy eff = Configuration.findEffigy(ce);
099                        if (eff != null) {
100                                StringAttribute sa = eff.identifier;
101                                if (sa != null) {
102                                        sa.setExpression(newName);
103                                }
104                        }
105                        
106                        return;
107                }
108                
109                
110                String oldDisplayName = StringUtilities.escapeForXML(ce
111                                .getDisplayName());
112
113                StringBuffer moml = new StringBuffer("<");
114                String elementName = ce.getElementName();
115                moml.append(elementName);
116                moml.append(" name=\"");
117                moml.append(oldName);
118                moml.append("\">");
119                if (!oldName.equals(newName)) {
120                        moml.append("<rename name=\"");
121                        moml.append(newName);
122                        moml.append("\"/>");
123                }
124                if (!oldDisplayName.equals(displayName)) {
125                        moml.append("<display name=\"");
126                        moml.append(displayName);
127                        moml.append("\"/>");
128                }
129
130                moml.append("</");
131                moml.append(elementName);
132                moml.append(">");
133
134                MoMLChangeRequest request = new MoMLChangeRequest(null, // originator
135                                parent, // context
136                                moml.toString(), // MoML code
137                                null); // base
138
139                RenameListener rl = new RenameListener();
140
141                request.addChangeListener(rl);
142                request.setUndoable(true);
143                parent.requestChange(request);
144                
145                                
146                KeplerLSID currentLSID = NamedObjId.getIdFor(ce);
147                notifyWorkflowRenameListeners(ce, oldName, newName, origLSID, currentLSID);
148                
149                // fixes bug 5101
150                Effigy eff = Configuration.findEffigy(ce);
151                if (eff != null) {
152                        StringAttribute sa = eff.identifier;
153                        if (sa != null) {
154                                sa.setExpression(newName);
155                        }
156                }
157                
158        }
159
160        
161        public static void notifyWorkflowRenameListeners(ComponentEntity ce, String oldName, 
162                        String newName, KeplerLSID oldLSID, KeplerLSID currentLSID){
163                
164                if (!oldLSID.equals(currentLSID) && oldName != null && !oldName.equals(newName)){               
165                        // notify any rename listeners
166                        WorkflowRenameManager.getInstance().renamedWorkflow(ce, 
167                                        oldLSID, currentLSID, oldName, newName);
168                }
169        }
170        
171        
172}