Skip to content

Commit

Permalink
Ondra zizka windup 1684 tech report boxes (#1222)
Browse files Browse the repository at this point in the history
* WINDUP-1684: Tech report boxes and punchcard report

* WINDUP-1684: Fixed unit tests, hid multi-level matrix behind an API and removed unused code

* WINDUP-1684: Fixed the mandatory effort points on the tech report punch card

* WINDUP-1684: Fixed another unit tests (it is unclear why these seem to work on master)

* WINDUP-1684: Fixed punchcard size in the case of stats models that attach at the module level (instead of application)
  • Loading branch information
jsight authored and mrizzi committed Nov 13, 2017
1 parent 5ab32d2 commit 151a804
Show file tree
Hide file tree
Showing 123 changed files with 9,638 additions and 353 deletions.
110 changes: 82 additions & 28 deletions config/api/src/main/java/org/jboss/windup/config/tags/Tag.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package org.jboss.windup.config.tags;


import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import org.apache.commons.collections4.set.UnmodifiableSet;

/**
* Represents a tag. Determined by it's lowercased name.
* The structure is not a tree - a tag may have multiple parents.
* Represents a tag. Determined by it's lowercased name. The structure is not a tree - a tag may have multiple "parents".
*
* Note that the "parent" and "contained tags" is misleading. The tags structure is in fact an oriented acyclic graph. (It could even be cyclic if we
* allowed for synonyms.) Better names would be "designated tags" and "designated by tags" or such.
*
* @author Ondrej Zizka
*/
Expand All @@ -20,37 +23,49 @@ public final class Tag
*/
private final Set<Tag> containedTags = new HashSet<>();
private final Set<Tag> parentTags = new HashSet<>();
private boolean isRoot = false;
private boolean isPrime = false;
private boolean isPseudo = false;
private boolean isRoot = false;
private String color = null;
private String title = null;

private Map<String, String> traits = null; // Not needed in most cases.

Tag(String name)
{
if( name == null )
throw new IllegalArgumentException("Tag name must not be null.");
this.name = name.toLowerCase();
this.name = normalizeName(name);
}

public static String normalizeName(String name)
{
if (name == null)
throw new IllegalArgumentException("Tag name must not be null.");
return name.toLowerCase().replace(' ', '-');
}

/**
* Tag name (ID), preferably kebab-style, e.g "java-ee-6".
*/
public String getName()
{
return name;
}


/**
* Which tags are designated by this tag; for instance, "java-ee" designates "ejb" and "jms".
*/
public Set<Tag> getContainedTags()
{
return UnmodifiableSet.unmodifiableSet(containedTags);
return Collections.unmodifiableSet(containedTags);
}


/**
* Which tags are designated by this tag; for instance, "seam" is designated by "web" and "framework:".
*/
public Set<Tag> getParentTags()
{
return UnmodifiableSet.unmodifiableSet(parentTags);
}

return Collections.unmodifiableSet(parentTags);
}

/**
* Loops are not checked here.
Expand All @@ -70,28 +85,28 @@ public void addContainingTag(Tag tag)
tag.containedTags.add(this);
}


@Override
public int hashCode()
{
return this.name.hashCode();
}


@Override
public boolean equals(Object obj)
{
if( obj == null )
if (obj == null)
return false;
if( getClass() != obj.getClass() )
if (getClass() != obj.getClass())
return false;
final Tag other = (Tag) obj;
if( !Objects.equals(this.name, other.name) )
if (!Objects.equals(this.name, other.name))
return false;
return true;
}


/**
* A root tag is that which was a root in the XML definition files. These serve as entry point shortcuts when browsing the graph.
*/
public boolean isRoot()
{
return this.isRoot;
Expand All @@ -102,46 +117,85 @@ public void setIsRoot(boolean isRoot)
this.isRoot = isRoot;
}

/**
* A "prime" tag is one which is an important group of subtags, suitable for showing in aggregated reports. For instance, "Java EE" is a good
* prime tag, as it may contain other technologies. Whereas "frameworks" is probably not a good prime tag as it's too general.
*/
public boolean isPrime()
{
return this.isPrime;
}

public void setIsPrime(boolean isPrime)
{
this.isPrime = isPrime;
}

/**
* Pseudo tags serve as grouping for contained tags, but are not suitable to be a root tag. They are also suitable for tagging related tags. In
* the XML files definition, such pseudo tags are often referred to by the parents="..." attribute. For instance, "framework:" or
* "application-server:" is a suitable pseudo tag, which can demarcate tags like "wicket" or "jboss-eap".
*
* By convention, the names are lower case, singular, and end with a colon.
*/
public boolean isPseudo()
{
return isPseudo;
}


public void setPseudo(boolean isPseudo)
{
this.isPseudo = isPseudo;
}


/**
* A color by which this tag should typically be represented in the UI elements like tags, boxes, chart lines, graph nodes, etc.
*/
public String getColor()
{
return color;
}


public void setColor(String color)
{
this.color = color;
}

/**
* Human readable title of technology this tag represents, e.g "Java EE 6".
*/
public String getTitle()
{
return title;
}

public void setTitle(String title)
{
this.title = title;
}

public String getTitleOrName()
{
return title != null ? title : name;
}

public String getTitle()
/**
* Returns the traits map, or null if it was not yet initialized.
*/
public Map<String, String> getTraits()
{
return title;
return traits;
}


public void setTitle(String title)
public Map<String, String> getOrCreateTraits()
{
this.title = title;
return traits != null ? traits : (traits = new HashMap<>());
}

@Override
public String toString()
{
return "#" + name + "(" + (containedTags == null ? '-' : containedTags.size()) + ')';
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
Expand All @@ -17,6 +18,7 @@
import javax.xml.parsers.SAXParserFactory;

import org.apache.commons.lang3.StringEscapeUtils;
import org.jboss.windup.util.exception.WindupException;
import org.xml.sax.SAXException;

/**
Expand Down Expand Up @@ -47,27 +49,55 @@ public void readTags(InputStream tagsXML)
}

/**
* Gets all tags that are "root" tags.
* Gets all tags that are "prime" tags.
*/
public List<Tag> getRootTags() {
public List<Tag> getPrimeTags()
{
return this.definedTags.values().stream()
.filter(Tag::isRoot)
.collect(Collectors.toList());
.filter(Tag::isPrime)
.collect(Collectors.toList());
}

/**
* Returns the tags that were root in the definition files. These serve as entry point shortcuts when browsing the graph. We could reduce this to
* just fewer as the root tags may be connected through parents="...".
*/
public List<Tag> getRootTags()
{
return this.definedTags.values().stream()
.filter(Tag::isRoot)
.collect(Collectors.toList());
}

/**
* Returns the {@link Tag} with the provided name.
*/
public Tag findTag(String tagName)
{
if (null == tagName)
throw new IllegalArgumentException("Looking for null tag name.");
return definedTags.get(Tag.normalizeName(tagName));
}

public Tag getTag(String tagName)
{
return definedTags.get(tagName);
Tag tag = findTag(tagName);
if (null == tag)
throw new WindupException("Tag does not exist: " + tagName);
return tag;
}

/**
* Gets the {@link Tag} with the given name or creates a new {@link Tag} if one does not already exist.
*
* @param isRef True if the given tag name is a reference, in which case it should already exist.
*/
public Tag getOrCreateTag(String tagName)
public Tag getOrCreateTag(String tagName, boolean isRef)
{
if (null == tagName)
throw new IllegalArgumentException("Looking for a null tag name.");
tagName = Tag.normalizeName(tagName);

synchronized (this.definedTags)
{
if (definedTags.containsKey(tagName))
Expand All @@ -81,19 +111,64 @@ public Tag getOrCreateTag(String tagName)
}
}

/**
* Returns all tags that designate this tag. E.g., for "tesla-model3", this would return "car", "vehicle", "vendor-tesla" etc.
*/
public Set<Tag> getAncestorTags(Tag tag)
{
Set<Tag> ancestors = new HashSet<>();
getAncestorTags(tag, ancestors);
return ancestors;
}

private void getAncestorTags(Tag tag, Set<Tag> putResultsHere)
{
for (Tag parentTag : tag.getParentTags())
{
if (!putResultsHere.add(parentTag))
continue; // Already visited.
getAncestorTags(parentTag, putResultsHere);
}
}

/**
* Returns all tags that are designated by this tag. E.g., for "vehicle", this would return "ship", "car", "tesla-model3", "bike", etc.
*/
public Set<Tag> getDescendantTags(Tag tag)
{
Set<Tag> ancestors = new HashSet<>();
getDescendantTags(tag, ancestors);
return ancestors;
}

private void getDescendantTags(Tag tag, Set<Tag> putResultsHere)
{
for (Tag childTag : tag.getContainedTags())
{
if (!putResultsHere.add(childTag))
continue; // Already visited.
getDescendantTags(childTag, putResultsHere);
}
}

/**
* Convenience method, calls this.isUnderTag(Tag superTag, Tag subTag).
*/
public boolean isUnderTag(String superTagName, String subTagName)
{
if (superTagName == null || subTagName == null)
return false;
throw new IllegalArgumentException("Looking for a null tag name.");

superTagName = Tag.normalizeName(superTagName);
subTagName = Tag.normalizeName(subTagName);

if (superTagName.equals(subTagName))
return false;

final Tag superTag = this.getTag(superTagName);
final Tag subTag = this.getTag(subTagName);
final Tag superTag = this.findTag(superTagName);
final Tag subTag = this.findTag(subTagName);
if (subTag == null || superTag == null)
return false;
return this.isUnderTag(superTag, subTag);
}

Expand All @@ -103,7 +178,7 @@ public boolean isUnderTag(String superTagName, String subTagName)
public boolean isUnderTag(Tag superTag, Tag subTag)
{
if (superTag == null || subTag == null)
return false;
throw new IllegalArgumentException("Looking for a null tag name.");

if (superTag.getName().equals(subTag.getName()))
return false;
Expand Down Expand Up @@ -148,14 +223,14 @@ public boolean isUnderTag(Tag superTag, Tag subTag)
public void writeTagsToJavaScript(Writer writer) throws IOException
{
writer.append("function fillTagService(tagService) {\n");
writer.append("\t// (name, isRoot, isPseudo, color), [parent tags]\n");
writer.append("\t// (name, isPrime, isPseudo, color), [parent tags]\n");
for (Tag tag : definedTags.values())
{
writer.append("\ttagService.registerTag(new Tag(");
escapeOrNull(tag.getName(), writer);
writer.append(", ");
escapeOrNull(tag.getTitle(), writer);
writer.append(", ").append("" + tag.isRoot())
writer.append(", ").append("" + tag.isPrime())
.append(", ").append("" + tag.isPseudo())
.append(", ");
escapeOrNull(tag.getColor(), writer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,4 @@ public TagService getTagService()
{
return tagService;
}


}
Loading

0 comments on commit 151a804

Please sign in to comment.