001/** 002 * '$Author: crawl $' 003 * '$Date: 2015-08-24 22:45:41 +0000 (Mon, 24 Aug 2015) $' 004 * '$Revision: 33631 $' 005 * 006 * For Details: 007 * http://www.kepler-project.org 008 * 009 * Copyright (c) 2010 The Regents of the 010 * University of California. All rights reserved. Permission is hereby granted, 011 * without written agreement and without license or royalty fees, to use, copy, 012 * modify, and distribute this software and its documentation for any purpose, 013 * provided that the above copyright notice and the following two paragraphs 014 * appear in all copies of this software. IN NO EVENT SHALL THE UNIVERSITY OF 015 * CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, 016 * OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS 017 * DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE 018 * POSSIBILITY OF SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY 019 * DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 020 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE 021 * SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 022 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 023 * ENHANCEMENTS, OR MODIFICATIONS. 024 */ 025package org.kepler.kar; 026 027import java.io.IOException; 028import java.net.URL; 029import java.util.HashSet; 030import java.util.Set; 031 032import com.sun.javadoc.ClassDoc; 033import com.sun.javadoc.RootDoc; 034 035import ptolemy.util.ClassUtilities; 036 037/** A doclet to find the paths of all super classes for an object. 038 * 039 * @author Daniel Crawl 040 * @version $Id: SuperClassPathFinderDoclet.java 33631 2015-08-24 22:45:41Z crawl $ 041 */ 042 043public class SuperClassPathFinderDoclet { 044 045 /** The entry point called from javadoc. */ 046 public static boolean start(RootDoc root) { 047 048 _classFiles.clear(); 049 050 try { 051 ClassDoc[] classes = root.classes(); 052 _className = classes[0].qualifiedName(); 053 for (int i = 0; i < classes.length; i++) { 054 String name = classes[i].qualifiedName(); 055 // skip nested classes 056 if(i > 0 && name.startsWith(_className)) { 057 //System.out.println("skipping nested class " + name); 058 continue; 059 } 060 String filename = getFileNameForClassName(name); 061 if (filename != null && !_classFiles.contains(filename)) { 062 _classFiles.add(filename); 063 _addSuperClasses(classes[i]); 064 } 065 } 066 } catch (Exception e) { 067 System.out.println("ERROR " + e.getClass() + ": " + e.getMessage()); 068 e.printStackTrace(); 069 } 070 return true; 071 } 072 073 /** Get the collection of path names. */ 074 public static Set<String> getClassFiles() { 075 return new HashSet<String>(_classFiles); 076 } 077 078 /** Get the class name of the primary object. */ 079 public static String getClassName() { 080 return _className; 081 } 082 083 /** Recursively add the super classes of the object. */ 084 private static void _addSuperClasses(ClassDoc classDoc) throws ClassNotFoundException { 085 ClassDoc superClassDoc = classDoc.superclass(); 086 if (superClassDoc != null) { 087 String name = superClassDoc.qualifiedName(); 088 String filename = getFileNameForClassName(name); 089 //System.out.println("name = " + name); 090 if (superClassDoc != null && filename != null && !_classFiles.contains(filename) 091 // for actors, stop at TypedAtomicActor and TypedCompositeActor 092 && !name.equals("ptolemy.actor.TypedAtomicActor") 093 && !name.equals("ptolemy.actor.TypedCompositeActor") 094 // for parameters stop at Variable 095 && !name.equals("ptolemy.data.expr.Variable") 096 // for directors stop at Attribute 097 && !name.equals("ptolemy.kernel.util.Attribute")) { 098 _classFiles.add(filename); 099 _addSuperClasses(superClassDoc); 100 } 101 } 102 } 103 104 /** Return the path for a fully-qualified class name. */ 105 public static String getFileNameForClassName(String className) throws ClassNotFoundException { 106 String filename = className.replace('.', '/'); 107 108 // Inner classes: Get rid of everything past the first $ 109 if (filename.indexOf("$") != -1) { 110 filename = filename.substring(0, filename.indexOf("$")); 111 } 112 113 filename += ".java"; 114 //System.out.println("filename = " + filename); 115 URL url = ClassLoader.getSystemResource(filename); 116 //System.out.println("url = " + url); 117 118 if(url == null) { 119 120 try { 121 url = ClassUtilities.sourceResource(filename); 122 } catch (IOException e) { 123 System.out.println("ERROR trying to find file for class " + className + ": " + e.getMessage()); 124 } 125 126 if(url == null) { 127 // see if class is a nested class 128 Class<?> clazz = null; 129 try { 130 clazz = Class.forName(className); 131 } catch(ClassNotFoundException e) { 132 System.out.println("WARNING: could not instiante class " + className + 133 " (Maybe it's a customized composite actor?)"); 134 return null; 135 } 136 if(clazz.getEnclosingClass() == null) { 137 System.out.println("WARNING: could not find path for class " + className); 138 }// else { System.out.println("ignoring nested class " + className); } 139 } 140 } 141 142 if(url != null) { 143 return url.getPath(); 144 } 145 return null; 146 147 } 148 149 /** A collection of path names. */ 150 private static final Set<String> _classFiles = new HashSet<String>(); 151 152 /** The class name of the primary object. */ 153 private static String _className; 154}