Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
");
// Create a color that matches the box background color, but is darker
final float darkness = 0.8f;
final int r = (int) (Integer.parseInt(boxBgColor.substring(0, 2), 16) * darkness);
final int g = (int) (Integer.parseInt(boxBgColor.substring(2, 4), 16) * darkness);
final int b = (int) (Integer.parseInt(boxBgColor.substring(4, 6), 16) * darkness);
final String darkerColor = String.format("#%s%s%s%s%s%s", Integer.toString(r >> 4, 16),
Integer.toString(r & 0xf, 16), Integer.toString(g >> 4, 16), Integer.toString(g & 0xf, 16),
Integer.toString(b >> 4, 16), Integer.toString(b & 0xf, 16));
// Class annotations
final AnnotationInfoList annotationInfo = ci.annotationInfo;
if (annotationInfo != null && !annotationInfo.isEmpty()) {
buf.append("
ANNOTATIONS
");
final AnnotationInfoList annotationInfoSorted = new AnnotationInfoList(annotationInfo);
CollectionUtils.sortIfNotEmpty(annotationInfoSorted);
for (final AnnotationInfo ai : annotationInfoSorted) {
final String annotationName = ai.getName();
if (!annotationName.startsWith("java.lang.annotation.")) {
buf.append("
");
buf.append("
");
htmlEncode(ai.toString(), buf);
buf.append("
");
}
}
}
// Fields
final FieldInfoList fieldInfo = ci.fieldInfo;
if (showFields && fieldInfo != null && !fieldInfo.isEmpty()) {
final FieldInfoList fieldInfoSorted = new FieldInfoList(fieldInfo);
CollectionUtils.sortIfNotEmpty(fieldInfoSorted);
for (int i = fieldInfoSorted.size() - 1; i >= 0; --i) {
// Remove serialVersionUID field
if (fieldInfoSorted.get(i).getName().equals("serialVersionUID")) {
fieldInfoSorted.remove(i);
}
}
if (!fieldInfoSorted.isEmpty()) {
buf.append("
");
for (final MethodInfo mi : methodInfoSorted) {
buf.append("
");
// Method annotations
// TODO: wrap this cell if the contents get too long
buf.append("
");
final AnnotationInfoList methodAnnotationInfo = mi.annotationInfo;
if (methodAnnotationInfo != null) {
for (final AnnotationInfo ai : methodAnnotationInfo) {
if (buf.charAt(buf.length() - 1) != ' ') {
buf.append(' ');
}
htmlEncode(ai.toString(), buf);
}
}
// Method modifiers
if (scanSpec.ignoreMethodVisibility) {
if (buf.charAt(buf.length() - 1) != ' ') {
buf.append(' ');
}
buf.append(mi.getModifiersStr());
}
// Method return type
if (buf.charAt(buf.length() - 1) != ' ') {
buf.append(' ');
}
if (!mi.getName().equals("")) {
// Don't list return type for constructors
final TypeSignature resultTypeSig = mi.getTypeSignatureOrTypeDescriptor().getResultType();
htmlEncode(
useSimpleNames ? resultTypeSig.toStringWithSimpleNames() : resultTypeSig.toString(),
buf);
} else {
buf.append("<constructor>");
}
buf.append("
");
// Method name
buf.append("
");
buf.append("");
if (mi.getName().equals("")) {
// Show class name for constructors
htmlEncode(ci.getSimpleName(), buf);
} else {
htmlEncode(mi.getName(), buf);
}
buf.append(" ");
buf.append("
");
// Method parameters
buf.append("
");
buf.append('(');
final MethodParameterInfo[] paramInfo = mi.getParameterInfo();
if (paramInfo.length != 0) {
for (int i = 0, wrapPos = 0; i < paramInfo.length; i++) {
if (i > 0) {
buf.append(", ");
wrapPos += 2;
}
if (wrapPos > PARAM_WRAP_WIDTH) {
buf.append("
");
wrapPos = 0;
}
// Param annotation
final AnnotationInfo[] paramAnnotationInfo = paramInfo[i].annotationInfo;
if (paramAnnotationInfo != null) {
for (final AnnotationInfo ai : paramAnnotationInfo) {
final String ais = ai.toString();
if (!ais.isEmpty()) {
if (buf.charAt(buf.length() - 1) != ' ') {
buf.append(' ');
}
htmlEncode(ais, buf);
wrapPos += 1 + ais.length();
if (wrapPos > PARAM_WRAP_WIDTH) {
buf.append("
"
+ "
");
wrapPos = 0;
}
}
}
}
// Param type
final TypeSignature paramTypeSig = paramInfo[i].getTypeSignatureOrTypeDescriptor();
final String paramTypeStr = useSimpleNames ? paramTypeSig.toStringWithSimpleNames()
: paramTypeSig.toString();
htmlEncode(paramTypeStr, buf);
wrapPos += paramTypeStr.length();
// Param name
final String paramName = paramInfo[i].getName();
if (paramName != null) {
buf.append(" ");
htmlEncode(paramName, buf);
wrapPos += 1 + paramName.length();
buf.append("");
}
}
}
buf.append(')');
buf.append("
");
}
buf.append("
");
buf.append("
");
}
}
buf.append("
");
buf.append(">]");
}
/**
* Generates a .dot file which can be fed into GraphViz for layout and visualization of the class graph. The
* sizeX and sizeY parameters are the image output size to use (in inches) when GraphViz is asked to render the
* .dot file.
*
* @param classInfoList
* the class info list
* @param sizeX
* the size X
* @param sizeY
* the size Y
* @param showFields
* whether to show fields
* @param showFieldTypeDependencyEdges
* whether to show field type dependency edges
* @param showMethods
* whether to show methods
* @param showMethodTypeDependencyEdges
* whether to show method type dependency edges
* @param showAnnotations
* whether to show annotations
* @param useSimpleNames
* whether to use simple names for classes
* @param scanSpec
* the scan spec
* @return the string
*/
static String generateGraphVizDotFile(final ClassInfoList classInfoList, final float sizeX, final float sizeY,
final boolean showFields, final boolean showFieldTypeDependencyEdges, final boolean showMethods,
final boolean showMethodTypeDependencyEdges, final boolean showAnnotations,
final boolean useSimpleNames, final ScanSpec scanSpec) {
final StringBuilder buf = new StringBuilder(1024 * 1024);
buf.append("digraph {\n");
buf.append("size=\"").append(sizeX).append(',').append(sizeY).append("\";\n");
buf.append("layout=dot;\n");
buf.append("rankdir=\"BT\";\n");
buf.append("overlap=false;\n");
buf.append("splines=true;\n");
buf.append("pack=true;\n");
buf.append("graph [fontname = \"Courier, Regular\"]\n");
buf.append("node [fontname = \"Courier, Regular\"]\n");
buf.append("edge [fontname = \"Courier, Regular\"]\n");
final ClassInfoList standardClassNodes = classInfoList.getStandardClasses();
final ClassInfoList interfaceNodes = classInfoList.getInterfaces();
final ClassInfoList annotationNodes = classInfoList.getAnnotations();
for (final ClassInfo node : standardClassNodes) {
buf.append('"').append(node.getName()).append('"');
labelClassNodeHTML(node, "box", STANDARD_CLASS_COLOR, showFields, showMethods, useSimpleNames, scanSpec,
buf);
buf.append(";\n");
}
for (final ClassInfo node : interfaceNodes) {
buf.append('"').append(node.getName()).append('"');
labelClassNodeHTML(node, "diamond", INTERFACE_COLOR, showFields, showMethods, useSimpleNames, scanSpec,
buf);
buf.append(";\n");
}
for (final ClassInfo node : annotationNodes) {
buf.append('"').append(node.getName()).append('"');
labelClassNodeHTML(node, "oval", ANNOTATION_COLOR, showFields, showMethods, useSimpleNames, scanSpec,
buf);
buf.append(";\n");
}
final Set allVisibleNodes = new HashSet<>();
allVisibleNodes.addAll(standardClassNodes.getNames());
allVisibleNodes.addAll(interfaceNodes.getNames());
allVisibleNodes.addAll(annotationNodes.getNames());
buf.append('\n');
for (final ClassInfo classNode : standardClassNodes) {
for (final ClassInfo directSuperclassNode : classNode.getSuperclasses().directOnly()) {
if (directSuperclassNode != null && allVisibleNodes.contains(directSuperclassNode.getName())
&& !directSuperclassNode.getName().equals("java.lang.Object")) {
// class --> superclass
buf.append(" \"").append(classNode.getName()).append("\" -> \"")
.append(directSuperclassNode.getName()).append("\" [arrowsize=2.5]\n");
}
}
for (final ClassInfo implementedInterfaceNode : classNode.getInterfaces().directOnly()) {
if (allVisibleNodes.contains(implementedInterfaceNode.getName())) {
// class --<> implemented interface
buf.append(" \"").append(classNode.getName()).append("\" -> \"")
.append(implementedInterfaceNode.getName())
.append("\" [arrowhead=diamond, arrowsize=2.5]\n");
}
}
if (showFieldTypeDependencyEdges && classNode.fieldInfo != null) {
for (final FieldInfo fi : classNode.fieldInfo) {
for (final ClassInfo referencedFieldType : fi.findReferencedClassInfo(/* log = */ null)) {
if (allVisibleNodes.contains(referencedFieldType.getName())) {
// class --[ ] field type (open box)
buf.append(" \"").append(referencedFieldType.getName()).append("\" -> \"")
.append(classNode.getName())
.append("\" [arrowtail=obox, arrowsize=2.5, dir=back]\n");
}
}
}
}
if (showMethodTypeDependencyEdges && classNode.methodInfo != null) {
for (final MethodInfo mi : classNode.methodInfo) {
for (final ClassInfo referencedMethodType : mi.findReferencedClassInfo(/* log = */ null)) {
if (allVisibleNodes.contains(referencedMethodType.getName())) {
// class --[#] field type (open box)
buf.append(" \"").append(referencedMethodType.getName()).append("\" -> \"")
.append(classNode.getName())
.append("\" [arrowtail=box, arrowsize=2.5, dir=back]\n");
}
}
}
}
}
for (final ClassInfo interfaceNode : interfaceNodes) {
for (final ClassInfo superinterfaceNode : interfaceNode.getInterfaces().directOnly()) {
if (allVisibleNodes.contains(superinterfaceNode.getName())) {
// interface --<> superinterface
buf.append(" \"").append(interfaceNode.getName()).append("\" -> \"")
.append(superinterfaceNode.getName()).append("\" [arrowhead=diamond, arrowsize=2.5]\n");
}
}
}
if (showAnnotations) {
for (final ClassInfo annotationNode : annotationNodes) {
for (final ClassInfo annotatedClassNode : annotationNode.getClassesWithAnnotationDirectOnly()) {
if (allVisibleNodes.contains(annotatedClassNode.getName())) {
// annotated class --o annotation
buf.append(" \"").append(annotatedClassNode.getName()).append("\" -> \"")
.append(annotationNode.getName()).append("\" [arrowhead=dot, arrowsize=2.5]\n");
}
}
for (final ClassInfo classWithMethodAnnotationNode : annotationNode
.getClassesWithMethodAnnotationDirectOnly()) {
if (allVisibleNodes.contains(classWithMethodAnnotationNode.getName())) {
// class with method annotation --o method annotation
buf.append(" \"").append(classWithMethodAnnotationNode.getName()).append("\" -> \"")
.append(annotationNode.getName()).append("\" [arrowhead=odot, arrowsize=2.5]\n");
}
}
for (final ClassInfo classWithMethodAnnotationNode : annotationNode
.getClassesWithFieldAnnotationDirectOnly()) {
if (allVisibleNodes.contains(classWithMethodAnnotationNode.getName())) {
// class with field annotation --o method annotation
buf.append(" \"").append(classWithMethodAnnotationNode.getName()).append("\" -> \"")
.append(annotationNode.getName()).append("\" [arrowhead=odot, arrowsize=2.5]\n");
}
}
}
}
buf.append('}');
return buf.toString();
}
/**
* Generate a .dot file which can be fed into GraphViz for layout and visualization of the class graph. The
* returned graph shows inter-class dependencies only. The sizeX and sizeY parameters are the image output size
* to use (in inches) when GraphViz is asked to render the .dot file. You must have called
* {@link ClassGraph#enableInterClassDependencies()} before scanning to use this method.
*
* @param classInfoList
* The list of nodes whose dependencies should be plotted in the graph.
* @param sizeX
* The GraphViz layout width in inches.
* @param sizeY
* The GraphViz layout width in inches.
* @param includeExternalClasses
* If true, include any dependency nodes in the graph that are not themselves in classInfoList.
* @return the GraphViz file contents.
* @throws IllegalArgumentException
* if this {@link ClassInfoList} is empty or {@link ClassGraph#enableInterClassDependencies()} was
* not called before scanning (since there would be nothing to graph).
*/
static String generateGraphVizDotFileFromInterClassDependencies(final ClassInfoList classInfoList,
final float sizeX, final float sizeY, final boolean includeExternalClasses) {
final StringBuilder buf = new StringBuilder(1024 * 1024);
buf.append("digraph {\n");
buf.append("size=\"").append(sizeX).append(',').append(sizeY).append("\";\n");
buf.append("layout=dot;\n");
buf.append("rankdir=\"BT\";\n");
buf.append("overlap=false;\n");
buf.append("splines=true;\n");
buf.append("pack=true;\n");
buf.append("graph [fontname = \"Courier, Regular\"]\n");
buf.append("node [fontname = \"Courier, Regular\"]\n");
buf.append("edge [fontname = \"Courier, Regular\"]\n");
final Set allVisibleNodes = new HashSet<>(classInfoList);
if (includeExternalClasses) {
for (final ClassInfo ci : classInfoList) {
allVisibleNodes.addAll(ci.getClassDependencies());
}
}
for (final ClassInfo ci : allVisibleNodes) {
buf.append('"').append(ci.getName()).append('"');
buf.append("[shape=").append(ci.isAnnotation() ? "oval" : ci.isInterface() ? "diamond" : "box")
.append(",style=filled,fillcolor=\"#").append(ci.isAnnotation() ? ANNOTATION_COLOR
: ci.isInterface() ? INTERFACE_COLOR : STANDARD_CLASS_COLOR)
.append("\",label=");
buf.append('<');
buf.append("