Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,32 @@ dependencies {
)
)

BuildUtils.addExternalDependency(
project,
new ExternalDependency(
"org.graphper:graph-support-core:${graphSupportVersion}",
"graph-support-core",
"graph-support",
"https://github.com/jamisonjiang/graph-support",
ExternalDependency.APACHE_2_LICENSE_NAME,
ExternalDependency.APACHE_2_LICENSE_URL,
"Graphviz Java API",
)
)

BuildUtils.addExternalDependency(
project,
new ExternalDependency(
"org.graphper:graph-support-dot:${graphSupportVersion}",
"graph-support-dot",
"graph-support",
"https://github.com/jamisonjiang/graph-support",
ExternalDependency.APACHE_2_LICENSE_NAME,
ExternalDependency.APACHE_2_LICENSE_URL,
"DOT parsing support",
)
)

BuildUtils.addExternalDependency(
project,
new ExternalDependency(
Expand Down
2 changes: 2 additions & 0 deletions api/src/org/labkey/api/ApiModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@
import org.labkey.api.util.SessionHelper;
import org.labkey.api.util.StringExpressionFactory;
import org.labkey.api.util.StringUtilsLabKey;
import org.labkey.api.util.SvgUtil;
import org.labkey.api.util.SystemMaintenance;
import org.labkey.api.util.SystemMaintenanceStartupListener;
import org.labkey.api.util.URIUtil;
Expand Down Expand Up @@ -439,6 +440,7 @@ public void registerServlets(ServletContext servletCtx)
StringExpressionFactory.TestCase.class,
StringUtilsLabKey.TestCase.class,
SubfolderWriter.TestCase.class,
SvgUtil.TestCase.class,
SwapQueue.TestCase.class,
TSVMapWriter.Tests.class,
TSVWriter.TestCase.class,
Expand Down
16 changes: 6 additions & 10 deletions api/src/org/labkey/api/attachments/SvgSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Strings;
import org.labkey.api.util.PageFlowUtil;
import org.labkey.api.util.SvgUtil;
import org.labkey.api.util.SvgUtil.Size;
import org.labkey.api.view.NotFoundException;

import java.io.BufferedReader;
Expand All @@ -19,8 +21,7 @@
public class SvgSource
{
private final String _filteredSvg;

private Float _height = null;
private final Float _height;

public SvgSource(String svg)
{
Expand All @@ -32,16 +33,11 @@ public SvgSource(String svg)
if (!svg.contains("xmlns=\"" + SVGDOMImplementation.SVG_NAMESPACE_URI + "\"") && !svg.contains("xmlns='" + SVGDOMImplementation.SVG_NAMESPACE_URI + "'"))
svg = svg.replace("<svg", "<svg xmlns='" + SVGDOMImplementation.SVG_NAMESPACE_URI + "'");

int idx = svg.indexOf("height=\"");
if (idx != -1)
{
int heightStart = idx + 8;
int end = svg.indexOf("\"", heightStart);
_height = Float.parseFloat(svg.substring(heightStart, end));
}
Size size = SvgUtil.readHeight(svg);
_height = size != null ? size.value() : null;

// remove xlink:title to prevent org.apache.batik.transcoder.TranscoderException (issue #16173)
svg = svg.replaceAll("xlink:title", "title");
svg = svg.replace("xlink:title", "title");

// Reject hrefs. See #45819.
if (Strings.CI.contains(svg, "xlink:href"))
Expand Down
43 changes: 20 additions & 23 deletions api/src/org/labkey/api/module/ModuleDependencySorter.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@

import org.apache.commons.collections4.MultiValuedMap;
import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.graphper.api.GraphResource;
import org.graphper.api.Graphviz;
import org.graphper.parser.DotParser;
import org.junit.Assert;
import org.junit.Test;
import org.labkey.api.collections.CaseInsensitiveHashSet;
import org.labkey.api.util.DotRunner;
import org.labkey.api.util.FileUtil;
import org.labkey.api.util.Pair;
import org.labkey.api.util.logging.LogHelper;

import java.io.File;
import java.util.ArrayList;
Expand All @@ -34,12 +36,12 @@
import java.util.stream.Collectors;

/**
* Orders modules so that each module will always be after all of the modules it depends on.
* User: jeckels
* Date: Jun 6, 2006
* Orders modules so that each module will always be after all the modules it depends on.
*/
public class ModuleDependencySorter
{
private static final Logger LOG = LogHelper.getLogger(ModuleDependencySorter.class, "Module dependency information");

public List<Module> sortModulesByDependencies(List<Module> modules)
{
List<Pair<Module, Set<String>>> dependencies = new ArrayList<>();
Expand Down Expand Up @@ -101,7 +103,7 @@ public List<Module> sortModulesByDependencies(List<Module> modules)
if (module.getName().equalsIgnoreCase("core"))
{
result.remove(i);
result.add(0, module);
result.addFirst(module);
break;
}
}
Expand All @@ -128,41 +130,36 @@ private Module findModuleWithoutDependencies(List<Pair<Module, Set<String>>> dep
throw new IllegalArgumentException("Module '" + moduleName + "' (" + entry.getKey().getClass().getName() + ") is listed as being dependent on itself.");
}

StringBuilder sb = new StringBuilder();
for (Pair<Module, Set<String>> dependencyInfo : dependencies)
{
if (!sb.isEmpty())
{
sb.append(", ");
}
sb.append(dependencyInfo.getKey().getName());
}
String involved = dependencies.stream()
.map(pair -> pair.getKey().getName())
.collect(Collectors.joining(", "));

// Generate an SVG diagram that shows all remaining dependencies
graphModuleDependencies(dependencies, "involved");

throw new IllegalArgumentException("Unable to resolve module dependencies. The following modules are somehow involved: " + sb);
throw new IllegalArgumentException("Unable to resolve module dependencies. The following modules are somehow involved: " + involved);
}


private void graphModuleDependencies(List<Pair<Module, Set<String>>> dependencies, @SuppressWarnings("SameParameterValue") String adjective)
{
Logger log = LogManager.getLogger(ModuleDependencySorter.class);

try
{
File dir = FileUtil.getTempDirectory();
String dot = buildDigraph(dependencies);
Graphviz graph = DotParser.parse(dot);
File svgFile = FileUtil.createTempFile("modules", ".svg", dir);
DotRunner runner = new DotRunner(dir, dot);
runner.addSvgOutput(svgFile);
runner.execute();

log.info("For a diagram of " + adjective + " module dependencies, see " + svgFile.getAbsolutePath());
try (GraphResource resource = graph.toSvg())
{
resource.save(svgFile.getParent(), svgFile.getName());
}

LOG.info("For a diagram of {} module dependencies, see {}", adjective, svgFile.getAbsolutePath());
}
catch (Exception e)
{
log.error("Error running dot", e);
LOG.error("Error running dot", e);
}
}

Expand Down
Loading
Loading