001/* An attribute that contains documentation for the container. 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.moml; 029 030import java.io.IOException; 031import java.io.Writer; 032import java.util.Iterator; 033import java.util.List; 034 035import ptolemy.kernel.util.ChangeRequest; 036import ptolemy.kernel.util.IllegalActionException; 037import ptolemy.kernel.util.InternalErrorException; 038import ptolemy.kernel.util.NameDuplicationException; 039import ptolemy.kernel.util.NamedObj; 040import ptolemy.kernel.util.Settable; 041import ptolemy.kernel.util.StringAttribute; 042import ptolemy.util.StringUtilities; 043 044/////////////////////////////////////////////////////////////////// 045//// Documentation 046 047/** 048 An attribute that contains documentation for the container. 049 <p> 050 The name of a documentation object can often be meaningful. Many times 051 the name can be used to specify important information about the type of 052 documentation. Unfortunately, all documentation objects are currently 053 treated the same. 054 055 @author Edward A. Lee 056 @version $Id$ 057 @since Ptolemy II 0.4 058 @Pt.ProposedRating Yellow (eal) 059 @Pt.AcceptedRating Yellow (neuendor) 060 */ 061public class Documentation extends StringAttribute { 062 /** Construct an attribute with the specified container and name. 063 * The documentation contained by the attribute is initially empty, 064 * but can be set using the setValue() method. 065 * @param container The container. 066 * @param name The name of the attribute. 067 * @exception IllegalActionException If the attribute is not of an 068 * acceptable class for the container. 069 * @exception NameDuplicationException If the name coincides with 070 * an attribute already in the container. 071 */ 072 public Documentation(NamedObj container, String name) 073 throws IllegalActionException, NameDuplicationException { 074 super(container, name); 075 setVisibility(Settable.EXPERT); 076 } 077 078 /////////////////////////////////////////////////////////////////// 079 //// public methods //// 080 081 /** Return as a single string all the documentation associated with 082 * the specified object. Each attribute of type of class Documentation 083 * that the object contains contributes to the documentation. 084 * The text contributed by each such attribute starts on a new line. 085 * If there are no such attributes, then null is returned. 086 * @param object The object to document. 087 * @return The documentation for the object. 088 */ 089 public static String consolidate(NamedObj object) { 090 List docList = object.attributeList(Documentation.class); 091 092 if (docList.size() > 0) { 093 StringBuffer doc = new StringBuffer(); 094 Iterator segments = docList.iterator(); 095 096 while (segments.hasNext()) { 097 Documentation segment = (Documentation) segments.next(); 098 doc.append(segment.getValueAsString()); 099 100 if (segments.hasNext()) { 101 doc.append("\n"); 102 } 103 } 104 105 return doc.toString(); 106 } else { 107 return null; 108 } 109 } 110 111 /** Write a MoML description of this object with the specified 112 * indentation depth. This class is directly supported by the MoML 113 * "doc" element, so we generate MoML of the form 114 * "<doc><i>documentation</i></doc>", where 115 * <i>documentation</i> is replaced by the string value of this 116 * attribute. If this object is not persistent, then write nothing. 117 * @param output The output stream to write to. 118 * @param depth The depth in the hierarchy, to determine indenting. 119 * @param name The name to use instead of the current name. 120 * @exception IOException If an I/O error occurs. 121 * @see NamedObj#_exportMoMLContents 122 * @see #isPersistent() 123 */ 124 @Override 125 public void exportMoML(Writer output, int depth, String name) 126 throws IOException { 127 if (_isMoMLSuppressed(depth)) { 128 return; 129 } 130 131 if (name.equals("_doc")) { 132 // Name is the default name. Omit. 133 output.write(_getIndentPrefix(depth) + "<doc>" 134 + StringUtilities.escapeForXML(getExpression()) 135 + "</doc>\n"); 136 } else { 137 // Name is not the default name. 138 output.write(_getIndentPrefix(depth) + "<doc name=\"" + name + "\">" 139 + StringUtilities.escapeForXML(getExpression()) 140 + "</doc>\n"); 141 } 142 } 143 144 /** Override the base class to remove this instance from 145 * its container if the argument is an empty string. 146 * The removal is done in a change request, so it may 147 * not take effect immediately. 148 * @param expression The value of the string attribute. 149 * @exception IllegalActionException If the change is not acceptable 150 * to the container. 151 */ 152 @Override 153 public void setExpression(String expression) throws IllegalActionException { 154 if (expression.equals("")) { 155 ChangeRequest request = new ChangeRequest(this, 156 "Delete empty doc tag.") { 157 @Override 158 protected void _execute() throws Exception { 159 setContainer(null); 160 } 161 }; 162 163 requestChange(request); 164 } else { 165 super.setExpression(expression); 166 } 167 } 168 169 /** Set the documentation string. 170 * @param value The documentation. 171 * @see #getValueAsString() 172 */ 173 public void setValue(String value) { 174 try { 175 setExpression(value); 176 } catch (IllegalActionException e) { 177 throw new InternalErrorException(e); 178 } 179 } 180 181 /** Get the documentation as a string, with the class name prepended. 182 * @return A string describing the object. 183 */ 184 @Override 185 public String toString() { 186 return "(" + getClass().getName() + ", " + getExpression() + ")"; 187 } 188}