Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
DocumentationManager |
|
| 7.25;7.25 |
1 | /* $Id: DocumentationManager.java 17846 2010-01-12 19:37:12Z linus $ | |
2 | ***************************************************************************** | |
3 | * Copyright (c) 2009 Contributors - see below | |
4 | * All rights reserved. This program and the accompanying materials | |
5 | * are made available under the terms of the Eclipse Public License v1.0 | |
6 | * which accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | * | |
9 | * Contributors: | |
10 | * tfmorris | |
11 | ***************************************************************************** | |
12 | * | |
13 | * Some portions of this file was previously release using the BSD License: | |
14 | */ | |
15 | ||
16 | // Copyright (c) 1996-2007 The Regents of the University of California. All | |
17 | // Rights Reserved. Permission to use, copy, modify, and distribute this | |
18 | // software and its documentation without fee, and without a written | |
19 | // agreement is hereby granted, provided that the above copyright notice | |
20 | // and this paragraph appear in all copies. This software program and | |
21 | // documentation are copyrighted by The Regents of the University of | |
22 | // California. The software program and documentation are supplied "AS | |
23 | // IS", without any accompanying services from The Regents. The Regents | |
24 | // does not warrant that the operation of the program will be | |
25 | // uninterrupted or error-free. The end-user understands that the program | |
26 | // was developed for research purposes and is advised not to rely | |
27 | // exclusively on the program for any reason. IN NO EVENT SHALL THE | |
28 | // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, | |
29 | // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, | |
30 | // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF | |
31 | // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF | |
32 | // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY | |
33 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
34 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE | |
35 | // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF | |
36 | // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, | |
37 | // UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | |
38 | ||
39 | package org.argouml.uml; | |
40 | ||
41 | import java.util.Collection; | |
42 | import java.util.Iterator; | |
43 | ||
44 | import org.argouml.application.api.Argo; | |
45 | import org.argouml.model.Model; | |
46 | import org.argouml.util.MyTokenizer; | |
47 | ||
48 | /** | |
49 | * This class handles the Documentation of ModelElements. | |
50 | * Documentation is represented internally by the tagged value "documentation", | |
51 | * but it has its own tab-panel to ease user handling. | |
52 | * | |
53 | */ | |
54 | 0 | public class DocumentationManager { |
55 | ||
56 | /** | |
57 | * The system's native line-ends, for when things are written to file. | |
58 | */ | |
59 | 0 | private static final String LINE_SEPARATOR = |
60 | System.getProperty("line.separator"); | |
61 | ||
62 | /** | |
63 | * This function returns the documentation in C-style comment format. | |
64 | * | |
65 | * @param o the ModelElement | |
66 | * @param indent the current indentation for new lines | |
67 | * @return the documentation, as a String | |
68 | */ | |
69 | public static String getDocs(Object o, String indent) { | |
70 | 0 | return getDocs(o, indent, "/** ", " * ", " */"); |
71 | } | |
72 | ||
73 | /** | |
74 | * @param o the ModelElement | |
75 | * @param indent the current indentation for new lines | |
76 | * @param header is the first line | |
77 | * @param prefix is inserted at every line before the doc | |
78 | * @param footer is the closing line | |
79 | * @return the string that represents the documentation | |
80 | * for the given ModelElement | |
81 | */ | |
82 | public static String getDocs(Object o, String indent, String header, | |
83 | String prefix, String footer) { | |
84 | 0 | String sResult = defaultFor(o, indent); |
85 | ||
86 | 0 | if (Model.getFacade().isAModelElement(o)) { |
87 | 0 | Iterator iter = Model.getFacade().getTaggedValues(o); |
88 | 0 | if (iter != null) { |
89 | 0 | while (iter.hasNext()) { |
90 | 0 | Object tv = iter.next(); |
91 | 0 | String tag = Model.getFacade().getTagOfTag(tv); |
92 | 0 | if (Argo.DOCUMENTATION_TAG.equals(tag) |
93 | || Argo.DOCUMENTATION_TAG_ALT.equals(tag)) { | |
94 | 0 | sResult = Model.getFacade().getValueOfTag(tv); |
95 | // give priority to standard documentation tag | |
96 | 0 | if (Argo.DOCUMENTATION_TAG.equals(tag)) { |
97 | 0 | break; |
98 | } | |
99 | } | |
100 | 0 | } |
101 | } | |
102 | } | |
103 | ||
104 | 0 | if (sResult == null) |
105 | 0 | return "(No comment)"; |
106 | ||
107 | 0 | StringBuffer result = new StringBuffer(); |
108 | 0 | if (header != null) { |
109 | 0 | result.append(header).append(LINE_SEPARATOR); |
110 | } | |
111 | ||
112 | 0 | if (indent != null) { |
113 | 0 | if (prefix != null) { |
114 | 0 | prefix = indent + prefix; |
115 | } | |
116 | ||
117 | 0 | if (footer != null) { |
118 | 0 | footer = indent + footer; |
119 | } | |
120 | } | |
121 | ||
122 | 0 | appendComment(result, prefix, sResult, 0); |
123 | ||
124 | 0 | if (footer != null) { |
125 | 0 | result.append(footer); |
126 | } | |
127 | ||
128 | 0 | return result.toString(); |
129 | } | |
130 | ||
131 | /** | |
132 | * @param o the ModelElement. If it is not a ModelElement, | |
133 | * then you'll get a IllegalArgumentException | |
134 | * @param s the string representing the documentation | |
135 | */ | |
136 | public static void setDocs(Object o, String s) { | |
137 | 0 | Object taggedValue = |
138 | Model.getFacade().getTaggedValue(o, Argo.DOCUMENTATION_TAG); | |
139 | 0 | if (taggedValue == null) { |
140 | 0 | taggedValue = |
141 | Model.getExtensionMechanismsFactory().buildTaggedValue( | |
142 | Argo.DOCUMENTATION_TAG, s); | |
143 | 0 | Model.getExtensionMechanismsHelper().addTaggedValue(o, taggedValue); |
144 | } else { | |
145 | 0 | Model.getExtensionMechanismsHelper().setValueOfTag(taggedValue, s); |
146 | } | |
147 | 0 | } |
148 | ||
149 | /** | |
150 | * Determine whether documentation is associated with the given | |
151 | * element or not. | |
152 | * | |
153 | * Added 2001-10-05 STEFFEN ZSCHALER for use by | |
154 | * org.argouml.language.java.generator.CodeGenerator | |
155 | * | |
156 | * @param o The given element. | |
157 | * @return true if the given element has docs. | |
158 | */ | |
159 | public static boolean hasDocs(Object o) { | |
160 | 0 | if (Model.getFacade().isAModelElement(o)) { |
161 | 0 | Iterator i = Model.getFacade().getTaggedValues(o); |
162 | ||
163 | 0 | if (i != null) { |
164 | 0 | while (i.hasNext()) { |
165 | 0 | Object tv = i.next(); |
166 | 0 | String tag = Model.getFacade().getTagOfTag(tv); |
167 | 0 | String value = Model.getFacade().getValueOfTag(tv); |
168 | 0 | if ((Argo.DOCUMENTATION_TAG.equals(tag) |
169 | || Argo.DOCUMENTATION_TAG_ALT.equals(tag)) | |
170 | && value != null && value.trim().length() > 0) { | |
171 | 0 | return true; |
172 | } | |
173 | 0 | } |
174 | } | |
175 | } | |
176 | 0 | return false; |
177 | } | |
178 | ||
179 | /** | |
180 | * Generate default documentation. | |
181 | * | |
182 | * @param o the ModelElement | |
183 | * @param indent the current indentation string for new lines | |
184 | * @return the default documentation | |
185 | */ | |
186 | public static String defaultFor(Object o, String indent) { | |
187 | 0 | if (Model.getFacade().isAClass(o)) { |
188 | // TODO: Needs localization | |
189 | 0 | return " A class that represents ...\n\n" |
190 | + indent + " @see OtherClasses\n" | |
191 | + indent + " @author your_name_here"; | |
192 | } | |
193 | 0 | if (Model.getFacade().isAAttribute(o)) { |
194 | ||
195 | 0 | return " An attribute that represents ..."; |
196 | } | |
197 | ||
198 | 0 | if (Model.getFacade().isAOperation(o)) { |
199 | 0 | return " An operation that does...\n\n" |
200 | + indent + " @param firstParam a description of this parameter"; | |
201 | } | |
202 | 0 | if (Model.getFacade().isAInterface(o)) { |
203 | 0 | return " An interface defining operations expected of ...\n\n" |
204 | + indent + " @see OtherClasses\n" | |
205 | + indent + " @author your_name_here"; | |
206 | } | |
207 | 0 | if (Model.getFacade().isAModelElement(o)) { |
208 | 0 | return "\n"; |
209 | } | |
210 | ||
211 | 0 | return null; |
212 | } | |
213 | ||
214 | ||
215 | //////////////////////////////////////////////////////////////// | |
216 | // comments | |
217 | ||
218 | /** | |
219 | * Get the comments (the notes in a diagram) for a modelelement.<p> | |
220 | * | |
221 | * This returns a c-style comments. | |
222 | * | |
223 | * @param o The modelelement. | |
224 | * @return a String. | |
225 | */ | |
226 | public static String getComments(Object o) { | |
227 | 0 | return getComments(o, "/*", " * ", " */"); |
228 | } | |
229 | ||
230 | /** | |
231 | * Get the comments (the notes in a diagram) for a modelelement. | |
232 | * | |
233 | * @return a string with the comments. | |
234 | * @param o The given modelelement. | |
235 | * @param header is the comment header. | |
236 | * @param prefix is the comment prefix (on every line). | |
237 | * @param footer is the comment footer. | |
238 | */ | |
239 | public static String getComments(Object o, | |
240 | String header, String prefix, | |
241 | String footer) { | |
242 | 0 | StringBuffer result = new StringBuffer(); |
243 | 0 | if (header != null) { |
244 | 0 | result.append(header).append(LINE_SEPARATOR); |
245 | } | |
246 | ||
247 | 0 | if (Model.getFacade().isAUMLElement(o)) { |
248 | 0 | Collection comments = Model.getFacade().getComments(o); |
249 | 0 | if (!comments.isEmpty()) { |
250 | 0 | int nlcount = 2; |
251 | 0 | for (Iterator iter = comments.iterator(); iter.hasNext();) { |
252 | 0 | Object c = iter.next(); |
253 | 0 | String s = Model.getFacade().getName(c); |
254 | 0 | nlcount = appendComment(result, |
255 | prefix, | |
256 | s, | |
257 | nlcount > 1 ? 0 : 1); | |
258 | 0 | } |
259 | 0 | } else { |
260 | 0 | return ""; |
261 | } | |
262 | 0 | } else { |
263 | 0 | return ""; |
264 | } | |
265 | ||
266 | 0 | if (footer != null) { |
267 | 0 | result.append(footer).append(LINE_SEPARATOR); |
268 | } | |
269 | ||
270 | 0 | return result.toString(); |
271 | } | |
272 | ||
273 | /** | |
274 | * Append a string to sb which is chopped into lines and each line | |
275 | * prefixed with prefix. | |
276 | * | |
277 | * @param sb the StringBuffer to append to. | |
278 | * @param prefix the prefix to each line. | |
279 | * @param comment the text to reformat. | |
280 | * @param nlprefix the number of empty lines to prefix the comment with. | |
281 | * @return the number of pending empty lines. | |
282 | */ | |
283 | private static int appendComment(StringBuffer sb, String prefix, | |
284 | String comment, int nlprefix) { | |
285 | 0 | int nlcount = 0; |
286 | ||
287 | 0 | for (; nlprefix > 0; nlprefix--) { |
288 | 0 | if (prefix != null) |
289 | 0 | sb.append(prefix); |
290 | 0 | sb.append(LINE_SEPARATOR); |
291 | 0 | nlcount++; |
292 | } | |
293 | ||
294 | 0 | if (comment == null) { |
295 | 0 | return nlcount; |
296 | } | |
297 | ||
298 | 0 | MyTokenizer tokens = new MyTokenizer(comment, |
299 | "", | |
300 | MyTokenizer.LINE_SEPARATOR); | |
301 | ||
302 | 0 | while (tokens.hasMoreTokens()) { |
303 | 0 | String s = tokens.nextToken(); |
304 | 0 | if (!s.startsWith("\r") && !s.startsWith("\n")) { |
305 | 0 | if (prefix != null) |
306 | 0 | sb.append(prefix); |
307 | 0 | sb.append(s); |
308 | 0 | sb.append(LINE_SEPARATOR); |
309 | 0 | nlcount = 0; |
310 | 0 | } else if (nlcount > 0) { |
311 | 0 | if (prefix != null) |
312 | 0 | sb.append(prefix); |
313 | 0 | sb.append(LINE_SEPARATOR); |
314 | 0 | nlcount++; |
315 | } else { | |
316 | 0 | nlcount++; |
317 | } | |
318 | 0 | } |
319 | ||
320 | 0 | return nlcount; |
321 | } | |
322 | ||
323 | } /* end class DocumentationManager */ | |
324 | ||
325 | ||
326 | ||
327 |