001: /*
002: * Create a graphviz graph based on the classes in the specified java
003: * source files.
004: *
005: * (C) Copyright 2002-2005 Diomidis Spinellis
006: *
007: * Permission to use, copy, and distribute this software and its
008: * documentation for any purpose and without fee is hereby granted,
009: * provided that the above copyright notice appear in all copies and that
010: * both that copyright notice and this permission notice appear in
011: * supporting documentation.
012: *
013: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
014: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
015: * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
016: *
017: * $Id: Options.java,v 1.87 2008/01/16 11:01:38 dds Exp $
018: *
019: */
020:
021: package org.umlgraph.doclet;
022:
023: import java.io.BufferedReader;
024: import java.io.File;
025: import java.io.FileInputStream;
026: import java.io.FileNotFoundException;
027: import java.io.IOException;
028: import java.io.InputStream;
029: import java.io.InputStreamReader;
030: import java.lang.reflect.Field;
031: import java.lang.reflect.Modifier;
032: import java.net.URL;
033: import java.util.HashMap;
034: import java.util.Map;
035: import java.util.Properties;
036: import java.util.Vector;
037: import java.util.regex.Matcher;
038: import java.util.regex.Pattern;
039: import java.util.regex.PatternSyntaxException;
040:
041: import com.sun.javadoc.ClassDoc;
042: import com.sun.javadoc.Tag;
043:
044: /**
045: * Represent the program options
046: * @version $Revision: 1.87 $
047: * @author <a href="http://www.spinellis.gr">Diomidis Spinellis</a>
048: */
049: public class Options implements Cloneable, OptionProvider {
050: // dot's font platform dependence workaround
051: private static String defaultFont;
052: private static String defaultItalicFont;
053: // reused often, especially in UmlGraphDoc, worth creating just once and reusing
054: private static final Pattern allPattern = Pattern.compile(".*");
055: protected static final String DEFAULT_EXTERNAL_APIDOC = "http://java.sun.com/j2se/1.4.2/docs/api/";
056:
057: static {
058: // use an appropriate font depending on the current operating system
059: // (on windows graphviz is unable to locate "Helvetica-Oblique"
060: if (System.getProperty("os.name").toLowerCase().contains(
061: "windows")) {
062: defaultFont = "arial";
063: defaultItalicFont = "ariali";
064: } else {
065: defaultFont = "Helvetica";
066: defaultItalicFont = "Helvetica-Oblique";
067: }
068: }
069:
070: // instance fields
071: Vector<Pattern> hidePatterns;
072: boolean showQualified;
073: boolean showAttributes;
074: boolean showEnumerations;
075: boolean showEnumConstants;
076: boolean showOperations;
077: boolean showConstructors;
078: boolean showVisibility;
079: boolean horizontal;
080: boolean showType;
081: boolean showComment;
082: String edgeFontName;
083: String edgeFontColor;
084: String edgeColor;
085: double edgeFontSize;
086: String nodeFontName;
087: String nodeFontAbstractName;
088: String nodeFontColor;
089: double nodeFontSize;
090: String nodeFillColor;
091: double nodeFontClassSize;
092: String nodeFontClassName;
093: String nodeFontClassAbstractName;
094: double nodeFontTagSize;
095: String nodeFontTagName;
096: double nodeFontPackageSize;
097: String nodeFontPackageName;
098: Shape shape;
099: String bgColor;
100: public String outputFileName;
101: String outputEncoding;
102: Map<Pattern, String> apiDocMap;
103: String apiDocRoot;
104: boolean postfixPackage;
105: boolean useGuillemot;
106: boolean findViews;
107: String viewName;
108: public String outputDirectory;
109: /*
110: * Numeric values are preferable to symbolic here.
111: * Symbolic reportedly fail on MacOSX, and also are
112: * more difficult to verify with XML tools.
113: */
114: /** Guillemot left (open) */
115: String guilOpen = "«"; // « \u00ab
116: /** Guillemot right (close) */
117: String guilClose = "»"; // » \u00bb
118: boolean inferRelationships;
119: boolean inferDependencies;
120: RelationPattern contextRelationPattern;
121: boolean useImports;
122: Visibility inferDependencyVisibility;
123: boolean inferDepInPackage;
124: RelationType inferRelationshipType;
125: private Vector<Pattern> collPackages;
126: boolean compact;
127: // internal option, used by UMLDoc to generate relative links between classes
128: boolean relativeLinksForSourcePackages;
129: // internal option, used by UMLDoc to force strict matching on the class names
130: // and avoid problems with packages in the template declaration making UmlGraph hide
131: // classes outside of them (for example, class gr.spinellis.Foo<T extends java.io.Serializable>
132: // would have been hidden by the hide pattern "java.*"
133: // TODO: consider making this standard behaviour
134: boolean strictMatching;
135:
136: Options() {
137: showQualified = false;
138: showAttributes = false;
139: showEnumConstants = false;
140: showOperations = false;
141: showVisibility = false;
142: showEnumerations = false;
143: showConstructors = false;
144: showType = false;
145: showComment = false;
146: edgeFontName = defaultFont;
147: edgeFontColor = "black";
148: edgeColor = "black";
149: edgeFontSize = 10;
150: nodeFontColor = "black";
151: nodeFontName = defaultFont;
152: nodeFontAbstractName = defaultItalicFont;
153: nodeFontSize = 10;
154: nodeFontClassSize = -1;
155: nodeFontClassName = null;
156: nodeFontClassAbstractName = null;
157: nodeFontTagSize = -1;
158: nodeFontTagName = null;
159: nodeFontPackageSize = -1;
160: nodeFontPackageName = null;
161: nodeFillColor = null;
162: bgColor = null;
163: shape = new Shape();
164: outputFileName = "graph.dot";
165: outputDirectory = null;
166: outputEncoding = "ISO-8859-1";
167: hidePatterns = new Vector<Pattern>();
168: apiDocMap = new HashMap<Pattern, String>();
169: apiDocRoot = null;
170: postfixPackage = false;
171: useGuillemot = true;
172: findViews = false;
173: viewName = null;
174: contextRelationPattern = new RelationPattern(
175: RelationDirection.BOTH);
176: inferRelationships = false;
177: inferDependencies = false;
178: inferDependencyVisibility = Visibility.PRIVATE;
179: inferDepInPackage = false;
180: useImports = false;
181: inferRelationshipType = RelationType.NAVASSOC;
182: collPackages = new Vector<Pattern>();
183: compact = false;
184: relativeLinksForSourcePackages = false;
185: }
186:
187: public Object clone() {
188: Options clone = null;
189: try {
190: clone = (Options) super .clone();
191: } catch (CloneNotSupportedException e) {
192: // Should not happen
193: }
194: // deep clone the hide and collection patterns
195: clone.hidePatterns = new Vector<Pattern>(hidePatterns);
196: clone.collPackages = new Vector<Pattern>(collPackages);
197: clone.apiDocMap = new HashMap<Pattern, String>(apiDocMap);
198: return clone;
199: }
200:
201: /** Most complete output */
202: public void setAll() {
203: showAttributes = true;
204: showEnumerations = true;
205: showEnumConstants = true;
206: showOperations = true;
207: showConstructors = true;
208: showVisibility = true;
209: showType = true;
210: }
211:
212: /**
213: * Return the number of arguments associated with the specified option.
214: * The return value includes the actual option.
215: * Will return 0 if the option is not supported.
216: */
217: public static int optionLength(String option) {
218: if (option.equals("-qualify") || option.equals("-horizontal")
219: || option.equals("-attributes")
220: || option.equals("-operations")
221: || option.equals("-constructors")
222: || option.equals("-visibility")
223: || option.equals("-types")
224: || option.equals("-commentname")
225: || option.equals("-all")
226: || option.equals("-postfixpackage")
227: || option.equals("-noguillemot")
228: || option.equals("-enumconstants")
229: || option.equals("-enumerations")
230: || option.equals("-views")
231: || option.equals("-inferrel")
232: || option.equals("-useimports")
233: || option.equals("-inferdep")
234: || option.equals("-inferdepinpackage")
235: || option.equals("-compact"))
236:
237: return 1;
238: else if (option.equals("-nodefillcolor")
239: || option.equals("-nodefontcolor")
240: || option.equals("-nodefontsize")
241: || option.equals("-nodefontname")
242: || option.equals("-nodefontabstractname")
243: || option.equals("-nodefontclasssize")
244: || option.equals("-nodefontclassname")
245: || option.equals("-nodefontclassabstractname")
246: || option.equals("-nodefonttagsize")
247: || option.equals("-nodefonttagname")
248: || option.equals("-nodefontpackagesize")
249: || option.equals("-nodefontpackagename")
250: || option.equals("-edgefontcolor")
251: || option.equals("-edgecolor")
252: || option.equals("-edgefontsize")
253: || option.equals("-edgefontname")
254: || option.equals("-shape") || option.equals("-output")
255: || option.equals("-outputencoding")
256: || option.equals("-bgcolor") || option.equals("-hide")
257: || option.equals("-apidocroot")
258: || option.equals("-apidocmap") || option.equals("-d")
259: || option.equals("-view")
260: || option.equals("-inferreltype")
261: || option.equals("-inferdepvis")
262: || option.equals("-collpackages")
263: || option.equals("-link"))
264: return 2;
265: else if (option.equals("-contextPattern"))
266: return 3;
267: else
268: return 0;
269: }
270:
271: /** Set the options based on a single option and its arguments */
272: void setOption(String[] opt) {
273: if (!opt[0].equals("-hide")
274: && optionLength(opt[0]) > opt.length) {
275: System.err.println("Skipping option '" + opt[0]
276: + "', missing argument");
277: return;
278: }
279:
280: if (opt[0].equals("-qualify")) {
281: showQualified = true;
282: } else if (opt[0].equals("-!qualify")) {
283: showQualified = false;
284: } else if (opt[0].equals("-horizontal")) {
285: horizontal = true;
286: } else if (opt[0].equals("-!horizontal")) {
287: horizontal = false;
288: } else if (opt[0].equals("-attributes")) {
289: showAttributes = true;
290: } else if (opt[0].equals("-!attributes")) {
291: showAttributes = false;
292: } else if (opt[0].equals("-enumconstants")) {
293: showEnumConstants = true;
294: } else if (opt[0].equals("-!enumconstants")) {
295: showEnumConstants = false;
296: } else if (opt[0].equals("-operations")) {
297: showOperations = true;
298: } else if (opt[0].equals("-!operations")) {
299: showOperations = false;
300: } else if (opt[0].equals("-enumerations")) {
301: showEnumerations = true;
302: } else if (opt[0].equals("-!enumerations")) {
303: showEnumerations = false;
304: } else if (opt[0].equals("-constructors")) {
305: showConstructors = true;
306: } else if (opt[0].equals("-!constructors")) {
307: showConstructors = false;
308: } else if (opt[0].equals("-visibility")) {
309: showVisibility = true;
310: } else if (opt[0].equals("-!visibility")) {
311: showVisibility = false;
312: } else if (opt[0].equals("-types")) {
313: showType = true;
314: } else if (opt[0].equals("-!types")) {
315: showType = false;
316: } else if (opt[0].equals("-commentname")) {
317: showComment = true;
318: } else if (opt[0].equals("-!commentname")) {
319: showComment = false;
320: } else if (opt[0].equals("-all")) {
321: setAll();
322: } else if (opt[0].equals("-bgcolor")) {
323: bgColor = opt[1];
324: } else if (opt[0].equals("-!bgcolor")) {
325: bgColor = null;
326: } else if (opt[0].equals("-edgecolor")) {
327: edgeColor = opt[1];
328: } else if (opt[0].equals("-!edgecolor")) {
329: edgeColor = "black";
330: } else if (opt[0].equals("-edgefontcolor")) {
331: edgeFontColor = opt[1];
332: } else if (opt[0].equals("-!edgefontcolor")) {
333: edgeFontColor = "black";
334: } else if (opt[0].equals("-edgefontname")) {
335: edgeFontName = opt[1];
336: } else if (opt[0].equals("-!edgefontname")) {
337: edgeFontName = defaultFont;
338: } else if (opt[0].equals("-edgefontsize")) {
339: edgeFontSize = Integer.parseInt(opt[1]);
340: } else if (opt[0].equals("-!edgefontsize")) {
341: edgeFontSize = 10;
342: } else if (opt[0].equals("-nodefontcolor")) {
343: nodeFontColor = opt[1];
344: } else if (opt[0].equals("-!nodefontcolor")) {
345: nodeFontColor = "black";
346: } else if (opt[0].equals("-nodefontname")) {
347: nodeFontName = opt[1];
348: } else if (opt[0].equals("-!nodefontname")) {
349: nodeFontName = defaultFont;
350: } else if (opt[0].equals("-nodefontabstractname")) {
351: nodeFontAbstractName = opt[1];
352: } else if (opt[0].equals("-!nodefontabstractname")) {
353: nodeFontAbstractName = defaultItalicFont;
354: } else if (opt[0].equals("-nodefontsize")) {
355: nodeFontSize = Integer.parseInt(opt[1]);
356: } else if (opt[0].equals("-!nodefontsize")) {
357: nodeFontSize = 10;
358: } else if (opt[0].equals("-nodefontclassname")) {
359: nodeFontClassName = opt[1];
360: } else if (opt[0].equals("-!nodefontclassname")) {
361: nodeFontClassName = null;
362: } else if (opt[0].equals("-nodefontclassabstractname")) {
363: nodeFontClassAbstractName = opt[1];
364: } else if (opt[0].equals("-!nodefontclassabstractname")) {
365: nodeFontClassAbstractName = null;
366: } else if (opt[0].equals("-nodefontclasssize")) {
367: nodeFontClassSize = Integer.parseInt(opt[1]);
368: } else if (opt[0].equals("-!nodefontclasssize")) {
369: nodeFontClassSize = -1;
370: } else if (opt[0].equals("-nodefonttagname")) {
371: nodeFontTagName = opt[1];
372: } else if (opt[0].equals("-!nodefonttagname")) {
373: nodeFontTagName = null;
374: } else if (opt[0].equals("-nodefonttagsize")) {
375: nodeFontTagSize = Integer.parseInt(opt[1]);
376: } else if (opt[0].equals("-!nodefonttagsize")) {
377: nodeFontTagSize = -1;
378: } else if (opt[0].equals("-nodefontpackagename")) {
379: nodeFontPackageName = opt[1];
380: } else if (opt[0].equals("-!nodefontpackagename")) {
381: nodeFontPackageName = null;
382: } else if (opt[0].equals("-nodefontpackagesize")) {
383: nodeFontPackageSize = Integer.parseInt(opt[1]);
384: } else if (opt[0].equals("-!nodefontpackagesize")) {
385: nodeFontPackageSize = -1;
386: } else if (opt[0].equals("-nodefillcolor")) {
387: nodeFillColor = opt[1];
388: } else if (opt[0].equals("-!nodefillcolor")) {
389: nodeFillColor = null;
390: } else if (opt[0].equals("-shape")) {
391: shape = new Shape(opt[1]);
392: } else if (opt[0].equals("-!shape")) {
393: shape = new Shape();
394: } else if (opt[0].equals("-output")) {
395: outputFileName = opt[1];
396: } else if (opt[0].equals("-!output")) {
397: outputFileName = "graph.dot";
398: } else if (opt[0].equals("-outputencoding")) {
399: outputEncoding = opt[1];
400: } else if (opt[0].equals("-!outputencoding")) {
401: outputEncoding = "ISO-8859-1";
402: } else if (opt[0].equals("-hide")) {
403: if (opt.length == 1) {
404: hidePatterns.clear();
405: hidePatterns.add(allPattern);
406: } else {
407: try {
408: hidePatterns.add(Pattern.compile(opt[1]));
409: } catch (PatternSyntaxException e) {
410: System.err.println("Skipping invalid pattern "
411: + opt[1]);
412: }
413: }
414: } else if (opt[0].equals("-!hide")) {
415: hidePatterns.clear();
416: } else if (opt[0].equals("-apidocroot")) {
417: apiDocRoot = fixApiDocRoot(opt[1]);
418: } else if (opt[0].equals("-!apidocroot")) {
419: apiDocRoot = null;
420: } else if (opt[0].equals("-apidocmap")) {
421: setApiDocMapFile(opt[1]);
422: } else if (opt[0].equals("-!apidocmap")) {
423: apiDocMap.clear();
424: } else if (opt[0].equals("-noguillemot")) {
425: guilOpen = "<<";
426: guilClose = ">>";
427: } else if (opt[0].equals("-!noguillemot")) {
428: guilOpen = "\u00ab";
429: guilClose = "\u00bb";
430: } else if (opt[0].equals("-view")) {
431: viewName = opt[1];
432: } else if (opt[0].equals("-!view")) {
433: viewName = null;
434: } else if (opt[0].equals("-views")) {
435: findViews = true;
436: } else if (opt[0].equals("-!views")) {
437: findViews = false;
438: } else if (opt[0].equals("-d")) {
439: outputDirectory = opt[1];
440: } else if (opt[0].equals("-!d")) {
441: outputDirectory = null;
442: } else if (opt[0].equals("-inferrel")) {
443: inferRelationships = true;
444: } else if (opt[0].equals("-!inferrel")) {
445: inferRelationships = false;
446: } else if (opt[0].equals("-inferreltype")) {
447: try {
448: inferRelationshipType = RelationType.valueOf(opt[1]
449: .toUpperCase());
450: } catch (IllegalArgumentException e) {
451: System.err
452: .println("Unknown association type " + opt[1]);
453: }
454: } else if (opt[0].equals("-!inferreltype")) {
455: inferRelationshipType = RelationType.NAVASSOC;
456: } else if (opt[0].equals("-inferdepvis")) {
457: try {
458: Visibility vis = Visibility.valueOf(opt[1]
459: .toUpperCase());
460: inferDependencyVisibility = vis;
461: } catch (IllegalArgumentException e) {
462: System.err
463: .println("Ignoring invalid visibility specification for "
464: + "dependency inference: " + opt[1]);
465: }
466: } else if (opt[0].equals("-!inferdepvis")) {
467: inferDependencyVisibility = Visibility.PRIVATE;
468: } else if (opt[0].equals("-inferdep")) {
469: inferDependencies = true;
470: } else if (opt[0].equals("-!inferdep")) {
471: inferDependencies = false;
472: } else if (opt[0].equals("-inferdepinpackage")) {
473: inferDepInPackage = true;
474: } else if (opt[0].equals("-!inferdepinpackage")) {
475: inferDepInPackage = false;
476: } else if (opt[0].equals("-useimports")) {
477: useImports = true;
478: } else if (opt[0].equals("-!useimports")) {
479: useImports = false;
480: } else if (opt[0].equals("-collpackages")) {
481: try {
482: collPackages.add(Pattern.compile(opt[1]));
483: } catch (PatternSyntaxException e) {
484: System.err
485: .println("Skipping invalid pattern " + opt[1]);
486: }
487: } else if (opt[0].equals("-!collpackages")) {
488: collPackages.clear();
489: } else if (opt[0].equals("-compact")) {
490: compact = true;
491: } else if (opt[0].equals("-!compact")) {
492: compact = false;
493: } else if (opt[0].equals("-postfixpackage")) {
494: postfixPackage = true;
495: } else if (opt[0].equals("-!postfixpackage")) {
496: postfixPackage = false;
497: } else if (opt[0].equals("-link")) {
498: addApiDocRoots(opt[1]);
499: } else if (opt[0].equals("-contextPattern")) {
500: RelationDirection d;
501: RelationType rt;
502: try {
503: d = RelationDirection.valueOf(opt[2].toUpperCase());
504: if (opt[1].equalsIgnoreCase("all")) {
505: contextRelationPattern = new RelationPattern(d);
506: } else {
507: rt = RelationType.valueOf(opt[1].toUpperCase());
508: contextRelationPattern.addRelation(rt, d);
509: }
510: } catch (IllegalArgumentException e) {
511:
512: }
513:
514: } else
515: ; // Do nothing, javadoc will handle the option or complain, if
516: // needed.
517: }
518:
519: /**
520: * Adds api doc roots from a link. The folder reffered by the link should contain a package-list
521: * file that will be parsed in order to add api doc roots to this configuration
522: * @param packageListUrl
523: */
524: private void addApiDocRoots(String packageListUrl) {
525: BufferedReader br = null;
526: packageListUrl = fixApiDocRoot(packageListUrl);
527: try {
528: URL url = new URL(packageListUrl + "/package-list");
529: br = new BufferedReader(new InputStreamReader(url
530: .openStream()));
531: String line = null;
532: while ((line = br.readLine()) != null) {
533: line = line + ".";
534: Pattern pattern = Pattern.compile(line.replace(".",
535: "\\.")
536: + "[^\\.]*");
537: apiDocMap.put(pattern, packageListUrl);
538: }
539: } catch (IOException e) {
540: System.err
541: .println("Errors happened while accessing the package-list file at "
542: + packageListUrl);
543: } finally {
544: if (br != null)
545: try {
546: br.close();
547: } catch (IOException e) {
548: }
549: }
550:
551: }
552:
553: /**
554: * Loads the property file referred by <code>apiDocMapFileName</code> and fills the apiDocMap
555: * accordingly
556: * @param apiDocMapFileName
557: */
558: void setApiDocMapFile(String apiDocMapFileName) {
559: try {
560: InputStream is = new FileInputStream(apiDocMapFileName);
561: Properties userMap = new Properties();
562: userMap.load(is);
563: for (Map.Entry mapEntry : userMap.entrySet()) {
564: try {
565: Pattern regex = Pattern.compile((String) mapEntry
566: .getKey());
567: String this Root = (String) mapEntry.getValue();
568: if (this Root != null) {
569: this Root = fixApiDocRoot(this Root);
570: apiDocMap.put(regex, this Root);
571: } else {
572: System.err.println("No URL for pattern "
573: + mapEntry.getKey());
574: }
575: } catch (PatternSyntaxException e) {
576: System.err.println("Skipping bad pattern "
577: + mapEntry.getKey());
578: }
579: }
580: } catch (FileNotFoundException e) {
581: System.err.println("File " + apiDocMapFileName
582: + " was not found: " + e);
583: } catch (IOException e) {
584: System.err
585: .println("Error reading the property api map file "
586: + apiDocMapFileName + ": " + e);
587: }
588: }
589:
590: /**
591: * Returns the appropriate URL "root" for an external class name. It will
592: * match the class name against the regular expressions specified in the
593: * <code>apiDocMap</code>; if a match is found, the associated URL
594: * will be returned.
595: *
596: * <b>NOTE:</b> The match order of the match attempts is the one specified by the
597: * constructor of the api doc root, so it depends on the order of "-link" and "-apiDocMap"
598: * parameters.
599: */
600: public String getApiDocRoot(String className) {
601: if (apiDocMap.isEmpty())
602: apiDocMap.put(Pattern.compile(".*"),
603: DEFAULT_EXTERNAL_APIDOC);
604:
605: for (Map.Entry<Pattern, String> mapEntry : apiDocMap.entrySet()) {
606: Pattern regex = mapEntry.getKey();
607: Matcher matcher = regex.matcher(className);
608: if (matcher.matches())
609: return mapEntry.getValue();
610: }
611: return null;
612: }
613:
614: /** Trim and append a file separator to the string */
615: private String fixApiDocRoot(String str) {
616: String fixed = null;
617: if (str != null) {
618: fixed = str.trim();
619: if (fixed.length() > 0) {
620: if (!File.separator.equals("/"))
621: fixed = fixed
622: .replace(File.separator.charAt(0), '/');
623: if (!fixed.endsWith("/"))
624: fixed = fixed + "/";
625: }
626: }
627: return fixed;
628: }
629:
630: /** Set the options based on the command line parameters */
631: public void setOptions(String[][] options) {
632: for (String s[] : options)
633: setOption(s);
634: }
635:
636: /** Set the options based on the tag elements of the ClassDoc parameter */
637: public void setOptions(ClassDoc p) {
638: if (p == null)
639: return;
640:
641: for (Tag tag : p.tags("opt")) {
642: String[] opt = StringUtil.tokenize(tag.text());
643: opt[0] = "-" + opt[0];
644: setOption(opt);
645: }
646: }
647:
648: /**
649: * Check if the supplied string matches an entity specified
650: * with the -hide parameter.
651: * @return true if the string matches.
652: */
653: public boolean matchesHideExpression(String s) {
654: for (Pattern hidePattern : hidePatterns) {
655: // micro-optimization because the "all pattern" is heavily used in UmlGraphDoc
656: if (hidePattern == allPattern)
657: return true;
658:
659: Matcher m = hidePattern.matcher(s);
660: if (strictMatching) {
661: if (m.matches()) {
662: return true;
663: }
664: } else if (m.find()) {
665: return true;
666: }
667: }
668: return false;
669: }
670:
671: /**
672: * Check if the supplied string matches an entity specified
673: * with the -hide parameter.
674: * @return true if the string matches.
675: */
676: public boolean matchesCollPackageExpression(String s) {
677: for (Pattern collPattern : collPackages) {
678: Matcher m = collPattern.matcher(s);
679: if (strictMatching) {
680: if (m.matches()) {
681: return true;
682: }
683: } else if (m.find()) {
684: return true;
685: }
686: }
687: return false;
688: }
689:
690: // ----------------------------------------------------------------
691: // OptionProvider methods
692: // ----------------------------------------------------------------
693:
694: public Options getOptionsFor(ClassDoc cd) {
695: Options localOpt = getGlobalOptions();
696: localOpt.setOptions(cd);
697: return localOpt;
698: }
699:
700: public Options getOptionsFor(String name) {
701: return getGlobalOptions();
702: }
703:
704: public Options getGlobalOptions() {
705: return (Options) clone();
706: }
707:
708: public void overrideForClass(Options opt, ClassDoc cd) {
709: // nothing to do
710: }
711:
712: public void overrideForClass(Options opt, String className) {
713: // nothing to do
714: }
715:
716: public String getDisplayName() {
717: return "general class diagram";
718: }
719:
720: public String toString() {
721: StringBuffer sb = new StringBuffer();
722: sb.append("UMLGRAPH OPTIONS\n");
723: for (Field f : this .getClass().getDeclaredFields()) {
724: if (!Modifier.isStatic(f.getModifiers())) {
725: f.setAccessible(true);
726: try {
727: sb.append(f.getName() + ":" + f.get(this ) + "\n");
728: } catch (Exception e) {
729: }
730: }
731: }
732: return sb.toString();
733: }
734:
735: }
|