Repository: tapestry-5 Updated Branches: refs/heads/master 6843db06f -> c4d8d6c30
Partial implementation of TAP5-2192 : a new Component Libraries tab was added to the T5Dashboard, presenting information and the list of components, pages and mixins from each one. Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/c4d8d6c3 Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/c4d8d6c3 Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/c4d8d6c3 Branch: refs/heads/master Commit: c4d8d6c3035fa278276e85cb4f37d37c9f90171b Parents: 6843db0 Author: Thiago H. de Paula Figueiredo <thiag...@apache.org> Authored: Sat Jul 5 15:08:12 2014 -0300 Committer: Thiago H. de Paula Figueiredo <thiag...@apache.org> Committed: Sat Jul 5 15:08:12 2014 -0300 ---------------------------------------------------------------------- .../corelib/pages/ComponentLibraries.java | 77 +++++++++++++++++++- .../services/ComponentLibraryInfo.java | 15 ++++ .../corelib/pages/ComponentLibraries.tml | 24 +++--- .../ComponentLibrariesCatalogPageTests.groovy | 53 ++++++++++++++ 4 files changed, 157 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/c4d8d6c3/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/ComponentLibraries.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/ComponentLibraries.java b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/ComponentLibraries.java index 6e27f6c..362d5f7 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/ComponentLibraries.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/ComponentLibraries.java @@ -19,12 +19,16 @@ import java.util.List; import org.apache.tapestry5.Block; import org.apache.tapestry5.annotations.Cached; +import org.apache.tapestry5.annotations.OnEvent; import org.apache.tapestry5.annotations.Property; import org.apache.tapestry5.annotations.UnknownActivationContextCheck; import org.apache.tapestry5.annotations.WhitelistAccessOnly; import org.apache.tapestry5.ioc.annotations.Inject; +import org.apache.tapestry5.json.JSONArray; +import org.apache.tapestry5.json.JSONObject; import org.apache.tapestry5.services.ComponentClassResolver; import org.apache.tapestry5.services.ComponentLibraryInfo; +import org.apache.tapestry5.util.TextStreamResponse; /** * Page used to describe the component libraries being used in the application. @@ -133,7 +137,12 @@ public class ComponentLibraries private String getClassName() { - final String className; + return getClassName(logicalName, type, componentClassResolver); + } + + private static String getClassName(String logicalName, Type type, ComponentClassResolver componentClassResolver) + { + String className; switch (type) { case PAGE: className = componentClassResolver.resolvePageNameToClassName(logicalName); break; @@ -148,5 +157,71 @@ public class ComponentLibraries { return logicalName.replace("core/", ""); } + + @OnEvent("json") + Object generateJSONDescription(String libraryName) + { + this.libraryName = libraryName; + JSONObject object = new JSONObject(); + object.put("libraryName", libraryName); + final ComponentLibraryInfo info = getInfo(); + if (info != null) + { + JSONObject infoJsonObject = new JSONObject(); + putIfNotNull("description", info.getDescription(), infoJsonObject); + putIfNotNull("homepage", info.getHomepageUrl(), infoJsonObject); + putIfNotNull("documentationUrl", info.getDocumentationUrl(), infoJsonObject); + putIfNotNull("javadocUrl", info.getJavadocUrl(), infoJsonObject); + putIfNotNull("groupId", info.getGroupId(), infoJsonObject); + putIfNotNull("artifactId", info.getArtifactId(), infoJsonObject); + putIfNotNull("version", info.getVersion(), infoJsonObject); + putIfNotNull("sourceBrowseUrl", info.getSourceBrowseUrl(), infoJsonObject); + putIfNotNull("sourceRootUrl", info.getSourceRootUrl(), infoJsonObject); + putIfNotNull("issueTrackerUrl", info.getIssueTrackerUrl(), infoJsonObject); + putIfNotNull("dependencyInfoUrl", info.getDependencyManagementInfoUrl(), infoJsonObject); + + object.put("info", infoJsonObject); + + } + + addClasses("components", filter(componentClassResolver.getComponentNames()), Type.COMPONENT, info, object); + addClasses("pages", filter(componentClassResolver.getPageNames()), Type.PAGE, info, object); + addClasses("mixins", filter(componentClassResolver.getMixinNames()), Type.MIXIN, info, object); + + return new TextStreamResponse("text/javascript", object.toString()); + + } + + private void addClasses(final String property, List<String> classes, Type type, + final ComponentLibraryInfo info, JSONObject object) + { + if (classes.size() > 0) + { + JSONArray classesJsonArray = new JSONArray(); + for (String logicalName : classes) + { + logicalName = logicalName.replace("core/", ""); + final String className = getClassName(logicalName, type, componentClassResolver); + JSONObject claszJsonObject = new JSONObject(); + claszJsonObject.put("logicalName", logicalName); + claszJsonObject.put("class", className); + if (info != null) + { + putIfNotNull("sourceUrl", info.getSourceUrl(className), claszJsonObject); + putIfNotNull("javadocUrl", info.getJavadocUrl(className), claszJsonObject); + } + classesJsonArray.put(claszJsonObject); + } + object.put(property, classesJsonArray); + } + } + + private void putIfNotNull(String propertyName, String value, JSONObject object) + { + if (value != null) + { + object.put(propertyName, value); + } + } } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/c4d8d6c3/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentLibraryInfo.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentLibraryInfo.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentLibraryInfo.java index 78d2cae..71c2743 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentLibraryInfo.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentLibraryInfo.java @@ -137,6 +137,21 @@ public final class ComponentLibraryInfo implements Serializable { return version; } + + /** + * Returns an URL decribing the dependency management information for this component library. + */ + public String getDependencyManagementInfoUrl() + { + String url = null; + if (isDependencyManagementInfoPresent()) + { + url = String.format( + "http://search.maven.org/#artifactdetails|%s|%s|version=%s|jar", + getGroupId(), getArtifactId(), getVersion()); + } + return url; + } public void setName(String name) { http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/c4d8d6c3/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/ComponentLibraries.tml ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/ComponentLibraries.tml b/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/ComponentLibraries.tml index 147912c..bfd5a39 100644 --- a/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/ComponentLibraries.tml +++ b/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/ComponentLibraries.tml @@ -1,7 +1,7 @@ <t:block id="content" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd" xmlns:p="tapestry:parameter"> - <h1><strong>${libraryNames.size()}</strong> component libraries found</h1> + <h1><strong>${libraryNames.size()}</strong> component libraries used</h1> <ul id="libraryList" class="list-group"> <li t:type="Loop" t:source="libraryNames" t:value="libraryName" class="list-group-item"> @@ -25,21 +25,21 @@ <dl class="dl-horizontal"> <dt>Homepage</dt> - <dd> + <dd class="homepage"> <t:if test="info.homepageUrl" else="message:not-informed"> <a href="${info.homepageUrl}">${info.homepageUrl}</a> </t:if> </dd> <dt>Documentation URL</dt> - <dd> + <dd class="documentationUrl"> <t:if test="info.documentationUrl" else="message:not-informed"> <a href="${info.documentationUrl}">${info.documentationUrl}</a> </t:if> </dd> - <dt>Source JavaDoc URL</dt> - <dd> + <dt>JavaDoc URL</dt> + <dd class="javadocUrl"> <t:if test="info.javadocUrl" else="message:not-informed"> <a href="${info.javadocUrl}">${info.javadocUrl}</a> </t:if> @@ -47,12 +47,12 @@ <t:if test="info.dependencyManagementInfoPresent"> <dt>Dependency information</dt> - <dd> + <dd class="dependencyInformation"> Group id <code class="groupId">${info.groupId}</code>, artifact id <code class="groupId">${info.artifactId}</code>, version. <code class="groupId">${info.version}</code> <br/> - <a href="http://search.maven.org/#artifactdetails|${info.groupId}|${info.artifactId}|version=${info.version}|jar" + <a href="${info.dependencyManagementInfoUrl}" target="_blank"> <em>More information at Maven Central Respository</em> </a> @@ -60,21 +60,21 @@ </t:if> <dt>Source browse URL</dt> - <dd> + <dd class="sourceBrowseUrl"> <t:if test="info.sourceBrowseUrl" else="message:not-informed"> <a href="${info.sourceBrowseUrl}">${info.sourceBrowseUrl}</a> </t:if> </dd> <dt>Source root URL</dt> - <dd> + <dd class="sourceRootUrl"> <t:if test="info.sourceRootUrl" else="message:not-informed"> <a href="${info.sourceRootUrl}">${info.sourceRootUrl}</a> </t:if> </dd> <dt>Issue tracker URL</dt> - <dd> + <dd class="issueTrackerUrl"> <t:if test="info.issueTrackerUrl" else="message:not-informed"> <a href="${info.issueTrackerUrl}">${info.issueTrackerUrl}</a> </t:if> @@ -83,8 +83,10 @@ </dl> </t:if> + + <a t:type="EventLink" t:event="json" t:context="libraryName">Generate JSON description</a> - <p t:type="If" t:test="!info">No additional information provided for <code>${libraryName}</code>.</p> + <p t:type="If" t:test="!info" class="noInformation">No additional information provided for <code>${libraryName}</code>.</p> <!-- <div t:type="Zone" t:id="pages" id="prop:libraryClientZoneClientId"> --> <!-- </div> --> http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/c4d8d6c3/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/ComponentLibrariesCatalogPageTests.groovy ---------------------------------------------------------------------- diff --git a/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/ComponentLibrariesCatalogPageTests.groovy b/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/ComponentLibrariesCatalogPageTests.groovy new file mode 100644 index 0000000..ea68c7b --- /dev/null +++ b/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/ComponentLibrariesCatalogPageTests.groovy @@ -0,0 +1,53 @@ +package org.apache.tapestry5.integration.app1 + +import org.apache.tapestry5.integration.TapestryCoreTestCase +import org.apache.tapestry5.test.TapestryTestConfiguration +import org.testng.annotations.Test + +@TapestryTestConfiguration(webAppFolder = "src/test/app1") +class ComponentLibrariesCatalogPageTests extends TapestryCoreTestCase +{ + @Test + void component_libraries_page() + { + open("${baseURL}t5dashboard/componentlibraries") + + // header + assertEquals "2 component libraries used", getText("//h1") + + // component library list + assertEquals 2, getXpathCount("//ul[@id='libraryList']/li") + assertEquals getText("//ul[@id='libraryList']/li[1]/a"), "core : Tapestry 5 Core Library" + assertEquals getText("//ul[@id='libraryList']/li[1]/p"), "The set of components, pages and mixins provided by Tapestry out-of-the-box." + assertEquals getText("//ul[@id='libraryList']/li[2]/a"), "lib/alpha" + assertFalse isElementPresent("//ul[@id='libraryList']/li[2]/p") + + // component library information + + // with ComponentLibraryInfo + assertEquals getText("css=#core h2"), "core : Tapestry 5 Core Library" + assertInfoLink "http://tapestry.apache.org", "css=#core .homepage" + assertInfoLink "http://tapestry.apache.org/documentation.html", "css=#core .documentationUrl" + assertInfoLink "http://tapestry.apache.org/current/apidocs/", "css=#core .javadocUrl" + assertInfoLink "https://git-wip-us.apache.org/repos/asf?p=tapestry-5.git;a=summary", "css=#core .sourceBrowseUrl" + assertInfoLink "https://git-wip-us.apache.org/repos/asf?p=tapestry-5.git;a=blob;f=tapestry-core/src/main/java", "css=#core .sourceRootUrl" + assertInfoLink "https://issues.apache.org/jira/browse/TAP5", "css=#core .issueTrackerUrl" + assertEquals getText("css=#core .dependencyInformation"), "Group id org.apache.tapestry, artifact id tapestry-core, version. 5.4.0 \n More information at Maven Central Respository" + assertEquals getAttribute("css=#core .dependencyInformation a@href"), "http://search.maven.org/#artifactdetails|org.apache.tapestry|tapestry-core|version=5.4.0|jar" + assertEquals getAttribute("//div[@id='core']//td/a[text()='JavaDoc']@href"), "http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/ActionLink.html" + assertEquals getAttribute("//div[@id='core']//td/a[text()='Source']@href"), "https://git-wip-us.apache.org/repos/asf?p=tapestry-5.git;a=blob;f=tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/ActionLink.java" + assertFalse isElementPresent("css=#core p.noInformation") + + // without ComponentLibraryInfo + assertEquals "lib/alpha", getText("css=#lib-alpha h2") + assertEquals getText("css=#lib-alpha p.noInformation"), "No additional information provided for lib/alpha." + + } + + def assertInfoLink(String url, String locator) + { + assertEquals getText(locator), url + assertEquals getAttribute(locator + " a@href"), url + } + +}