Repository: tapestry-5 Updated Branches: refs/heads/master ee0220c64 -> 6843db06f
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/6843db06 Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/6843db06 Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/6843db06 Branch: refs/heads/master Commit: 6843db06f07427cdc00e2b556dcb1077269a134b Parents: ee0220c Author: Thiago H. de Paula Figueiredo <thiag...@apache.org> Authored: Fri Jul 4 16:48:43 2014 -0300 Committer: Thiago H. de Paula Figueiredo <thiag...@apache.org> Committed: Fri Jul 4 16:48:43 2014 -0300 ---------------------------------------------------------------------- .../corelib/pages/ComponentLibraries.java | 152 +++++++++ .../tapestry5/corelib/pages/ServiceStatus.java | 2 +- .../services/ComponentClassResolverImpl.java | 34 ++ .../tapestry5/modules/DashboardModule.java | 3 +- .../tapestry5/modules/TapestryModule.java | 18 +- .../services/ComponentClassResolver.java | 24 +- .../services/ComponentLibraryInfo.java | 324 +++++++++++++++++++ .../tapestry5/services/LibraryMapping.java | 37 ++- .../org/apache/tapestry5/core.properties | 7 +- .../corelib/pages/ComponentLibraries.tml | 126 ++++++++ 10 files changed, 717 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/6843db06/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 new file mode 100644 index 0000000..6e27f6c --- /dev/null +++ b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/ComponentLibraries.java @@ -0,0 +1,152 @@ +// Copyright 2014 The Apache Software Foundation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package org.apache.tapestry5.corelib.pages; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.tapestry5.Block; +import org.apache.tapestry5.annotations.Cached; +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.services.ComponentClassResolver; +import org.apache.tapestry5.services.ComponentLibraryInfo; + +/** + * Page used to describe the component libraries being used in the application. + * Notice: the implementation of this page was done to avoid creating components, so the + * Tapestry 5 Core Library didn't get polluted with internal-only components. + */ +@UnknownActivationContextCheck(false) +@WhitelistAccessOnly +public class ComponentLibraries +{ + + private static enum Type { PAGE, COMPONENT, MIXIN } + + @Inject + private ComponentClassResolver componentClassResolver; + + @Property + private String libraryName; + + @Property + private String logicalName; + + @Property + private List<String> logicalNames; + + @Property + private String headerName; + + @Property + private List<String> pages; + + @Property + private List<String> components; + + @Property + private List<String> mixins; + + private Type type; + + @Inject + private Block classesTable; + + @Cached(watch="libraryName") + public ComponentLibraryInfo getInfo() + { + return componentClassResolver.getComponentLibraryInfo(libraryName); + } + + public List<String> getLibraryNames() { + return componentClassResolver.getLibraryNames(); + } + + public String getLibraryClientId() + { + return libraryName.replace("/", "-"); + } + + private List<String> filter(final List<String> allNames) + { + List<String> logicalNames = new ArrayList<String>(); + for (String name : allNames) + { + + if (name.startsWith(libraryName + "/") && !(libraryName.equals("core") && name.endsWith("Test"))) + { + logicalNames.add(name); + } + } + + return logicalNames; + } + + public Block getComponentsTable() + { + logicalNames = filter(componentClassResolver.getComponentNames()); + type = Type.COMPONENT; + headerName = "Components"; + return classesTable; + } + + public Block getPagesTable() + { + logicalNames = filter(componentClassResolver.getPageNames()); + type = Type.PAGE; + headerName = "Pages"; + return classesTable; + } + + public Block getMixinsTable() + { + logicalNames = filter(componentClassResolver.getMixinNames()); + type = Type.MIXIN; + headerName = "Mixins"; + return classesTable; + } + + public String getSourceUrl() + { + return getInfo() != null ? getInfo().getSourceUrl(getClassName()) : null; + } + + public String getJavaDocUrl() + { + return getInfo() != null ? getInfo().getJavadocUrl(getClassName()) : null; + } + + private String getClassName() + { + final String className; + switch (type) + { + case PAGE: className = componentClassResolver.resolvePageNameToClassName(logicalName); break; + case COMPONENT: className = componentClassResolver.resolveComponentTypeToClassName(logicalName); break; + case MIXIN: className = componentClassResolver.resolveMixinTypeToClassName(logicalName); break; + default: className = null; // should never happen + } + return className; + } + + public String getSimpleLogicalName() + { + return logicalName.replace("core/", ""); + } + +} http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/6843db06/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/ServiceStatus.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/ServiceStatus.java b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/ServiceStatus.java index 4c99023..55a3b62 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/ServiceStatus.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/ServiceStatus.java @@ -62,7 +62,7 @@ public class ServiceStatus model.addEmpty("serviceInterface"); // There's no line number information for interfaces, so we'll reorder the - // proprieties manually. + // properties manually. model.reorder("serviceId", "serviceInterface", "scope", "status"); } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/6843db06/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentClassResolverImpl.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentClassResolverImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentClassResolverImpl.java index cad9404..ba027e4 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentClassResolverImpl.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentClassResolverImpl.java @@ -24,6 +24,7 @@ import org.apache.tapestry5.ioc.services.ClassNameLocator; import org.apache.tapestry5.ioc.util.AvailableValues; import org.apache.tapestry5.ioc.util.UnknownValueException; import org.apache.tapestry5.services.ComponentClassResolver; +import org.apache.tapestry5.services.ComponentLibraryInfo; import org.apache.tapestry5.services.InvalidationListener; import org.apache.tapestry5.services.LibraryMapping; import org.apache.tapestry5.services.transform.ControlledPackageType; @@ -51,6 +52,9 @@ public class ComponentClassResolverImpl implements ComponentClassResolver, Inval // Map from library name to a list of root package names (usuallly just one). private final Map<String, List<String>> libraryNameToPackageNames = CollectionFactory.newCaseInsensitiveMap(); + // Map from library name to a ComponentLibraryInfo + private final Map<String, ComponentLibraryInfo> libraryNameToInfo = CollectionFactory.newCaseInsensitiveMap(); + private final Map<String, ControlledPackageType> packageNameToType = CollectionFactory.newMap(); /** @@ -255,6 +259,8 @@ public class ComponentClassResolverImpl implements ComponentClassResolver, Inval for (LibraryMapping mapping : mappings) { String libraryName = mapping.libraryName; + + libraryNameToInfo.put(libraryName, mapping.getComponentLibraryInfo()); List<String> packages = this.libraryNameToPackageNames.get(libraryName); @@ -453,6 +459,28 @@ public class ComponentClassResolverImpl implements ComponentClassResolver, Inval return result; } + public List<String> getComponentNames() + { + Data data = getData(); + + List<String> result = CollectionFactory.newList(data.componentToClassName.keySet()); + + Collections.sort(result); + + return result; + } + + public List<String> getMixinNames() + { + Data data = getData(); + + List<String> result = CollectionFactory.newList(data.mixinToClassName.keySet()); + + Collections.sort(result); + + return result; + } + public String resolveComponentTypeToClassName(final String componentType) { Data data = getData(); @@ -669,4 +697,10 @@ public class ComponentClassResolverImpl implements ComponentClassResolver, Inval } } } + + public ComponentLibraryInfo getComponentLibraryInfo(String libraryName) + { + return libraryNameToInfo.get(libraryName); + } + } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/6843db06/tapestry-core/src/main/java/org/apache/tapestry5/modules/DashboardModule.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/modules/DashboardModule.java b/tapestry-core/src/main/java/org/apache/tapestry5/modules/DashboardModule.java index 22abd21..9eccdc1 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/modules/DashboardModule.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/modules/DashboardModule.java @@ -1,4 +1,4 @@ -// Copyright 2013 The Apache Software Foundation +// Copyright 2013, 2014 The Apache Software Foundation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -33,5 +33,6 @@ public class DashboardModule { configuration.add("Pages", new DashboardTab("Pages", "core/PageCatalog")); configuration.add("Services", new DashboardTab("Services", "core/ServiceStatus")); + configuration.add("Libraries", new DashboardTab("ComponentLibraries", "core/ComponentLibraries")); } } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/6843db06/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java b/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java index 50d03b4..8e3e070 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java @@ -443,8 +443,24 @@ public final class TapestryModule @Symbol(InternalConstants.TAPESTRY_APP_PACKAGE_PARAM) String appRootPackage) { - configuration.add(new LibraryMapping(InternalConstants.CORE_LIBRARY, "org.apache.tapestry5.corelib")); + + ComponentLibraryInfo info = new ComponentLibraryInfo(); + info.setName("Tapestry 5 Core Library"); + info.setDescription("The set of components, pages and mixins provided by Tapestry out-of-the-box."); + info.setHomepageUrl("http://tapestry.apache.org"); + info.setDocumentationUrl("http://tapestry.apache.org/documentation.html"); + info.setSourceBrowseUrl("https://git-wip-us.apache.org/repos/asf?p=tapestry-5.git;a=summary"); + info.setSourceRootUrl("https://git-wip-us.apache.org/repos/asf?p=tapestry-5.git;a=blob;f=tapestry-core/src/main/java"); + info.setJavadocUrl("http://tapestry.apache.org/current/apidocs/"); + info.setIssueTrackerUrl("https://issues.apache.org/jira/browse/TAP5"); + info.setGroupId("org.apache.tapestry"); + info.setArtifactId("tapestry-core"); + info.setVersion("5.4.0"); + info.setSourceUrlResolver(new ComponentLibraryInfo.GitWebMavenSourceUrlResolver()); + + configuration.add(new LibraryMapping(InternalConstants.CORE_LIBRARY, "org.apache.tapestry5.corelib", info)); configuration.add(new LibraryMapping("", appRootPackage)); + } /** http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/6843db06/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentClassResolver.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentClassResolver.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentClassResolver.java index f6e8a1f..d6e3049 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentClassResolver.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentClassResolver.java @@ -15,6 +15,7 @@ package org.apache.tapestry5.services; import org.apache.tapestry5.Asset; +import org.apache.tapestry5.ioc.annotations.IncompatibleChange; import org.apache.tapestry5.ioc.annotations.UsesConfiguration; import org.apache.tapestry5.ioc.services.ClassNameLocator; import org.apache.tapestry5.services.transform.ControlledPackageType; @@ -67,6 +68,20 @@ public interface ComponentClassResolver List<String> getPageNames(); /** + * Returns a list of all component names, in sorted order. These are the "canonical" component names. + * @since 5.4 + */ + @IncompatibleChange(release = "5.4", details = "added method") + List<String> getComponentNames(); + + /** + * Returns a list of all mixin names, in sorted order. These are the "canonical" mixin names. + * @since 5.4 + */ + @IncompatibleChange(release = "5.4", details = "added method") + List<String> getMixinNames(); + + /** * Converts a fully qualified page class name into a page name (often, for inclusion as part of the URI). This value * may later be passed to {@link #resolvePageNameToClassName(String)}. * @@ -132,7 +147,14 @@ public interface ComponentClassResolver * @since 5.4 */ List<String> getLibraryNames(); - + + /** + * Returns an object encapsulating information about a component library, if provided. + * @param libraryName the library name (prefix). + * @return a {@link ComponentLibraryInfo} or <code>null</code> + */ + ComponentLibraryInfo getComponentLibraryInfo(String libraryName); + /** * Used to identify which packages are controlled packages (from which components are loaded). Future expansion * may allow for additional packages which are live reloaded but not components (or perhaps are transformed, but not http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/6843db06/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 new file mode 100644 index 0000000..78d2cae --- /dev/null +++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentLibraryInfo.java @@ -0,0 +1,324 @@ +// Copyright 2014 The Apache Software Foundation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package org.apache.tapestry5.services; + +import java.io.Serializable; + +/** + * Class that encapsulates information about a component library, going beyond what a library mapping + * provides. + * + * @see LibraryMapping + * @see SourceUrlResolver + * @since 5.4 + */ +public final class ComponentLibraryInfo implements Serializable +{ + private static final long serialVersionUID = 1L; + + private LibraryMapping libraryMapping; + + private SourceUrlResolver sourceUrlResolver; + + private String name, description, homepageUrl, documentationUrl, sourceBrowseUrl, issueTrackerUrl, sourceRootUrl, + javadocUrl, groupId, artifactId, version; + + /** + * Returns the actual name of the component library (not the identifier). + * For example, "Tapestry 5 Core Library". + */ + public String getName() + { + return name; + } + + /** + * Returns a description of the component library. + * For example, "The set of components, pages and mixins provided by Tapestry out-of-the-box.". + */ + public String getDescription() + { + return description; + } + + /** + * Returns the URL of the homepage of the component library. + * For example, "http://tapestry.apache.org". + */ + public String getHomepageUrl() + { + return homepageUrl; + } + + /** + * Returns the URL of the component library's documentation. + * For example, "http://tapestry.apache.org/documentation.html". + */ + public String getDocumentationUrl() + { + return documentationUrl; + } + + /** + * Returns the URL where the component library's source can be browsed. + * For example, "https://git-wip-us.apache.org/repos/asf?p=tapestry-5.git;a=summary". + */ + public String getSourceBrowseUrl() + { + return sourceBrowseUrl; + } + + /** + * Returns the URL where the root folder of component library's source can be found. + * For example, "https://git-wip-us.apache.org/repos/asf?p=tapestry-5.git;a=tree". + */ + public String getSourceRootUrl() + { + return sourceRootUrl; + } + + /** + * Returns the URL of the component's library issue tracker. + * For example, "https://issues.apache.org/jira/browse/TAP5". + */ + public String getIssueTrackerUrl() + { + return issueTrackerUrl; + } + + /** + * Returns the URL of the component library's JavaDoc URL. + * For example, "http://tapestry.apache.org/current/apidocs/" + */ + public String getJavadocUrl() + { + return javadocUrl; + } + + /** + * Returns the component library's group id for dependency management tools like Maven and Gradle. + * For example, "org.apache.tapestry". + * @see #artifactId + * @see #version + */ + public String getGroupId() + { + return groupId; + } + + /** + * Returns the component library's group id for dependency management tools like Maven and Gradle. + * For example, "tapestry-core". + * @see #groupId + * @see #version + */ + public String getArtifactId() + { + return artifactId; + } + + /** + * Return the component library version. For example, "5.4.0". + * @see #artifactId + * @see #groupId + */ + public String getVersion() + { + return version; + } + + public void setName(String name) + { + if (this.name != null) throwExceptionIfAlreadySet("name", name); + this.name = name; + } + + public void setDescription(String description) + { + if (this.description != null) throwExceptionIfAlreadySet("description", description); + this.description = description; + } + + public void setHomepageUrl(String homepageUrl) + { + if (this.homepageUrl != null) throwExceptionIfAlreadySet("homepageUrl", homepageUrl); + this.homepageUrl = homepageUrl; + } + + public void setDocumentationUrl(String documentationUrl) + { + if (this.documentationUrl != null) throwExceptionIfAlreadySet("documentationUrl", documentationUrl); + this.documentationUrl = documentationUrl; + } + + public void setSourceBrowseUrl(String sourceBrowseUrl) + { + if (this.sourceBrowseUrl != null) throwExceptionIfAlreadySet("sourceBrowseUrl", sourceBrowseUrl); + this.sourceBrowseUrl = sourceBrowseUrl; + } + + public void setSourceRootUrl(String sourceRootUrl) + { + if (this.sourceRootUrl != null) throwExceptionIfAlreadySet("sourceRootUrl", sourceRootUrl); + this.sourceRootUrl = sourceRootUrl; + } + + public void setJavadocUrl(String javadocUrl) + { + if (this.javadocUrl != null) throwExceptionIfAlreadySet("javadocUrl", javadocUrl); + this.javadocUrl = javadocUrl; + } + + public void setVersion(String version) + { + if (this.version != null) throwExceptionIfAlreadySet("version", version); + this.version = version; + } + + public void setGroupId(String groupId) + { + if (this.groupId != null) throwExceptionIfAlreadySet("groupId", artifactId); + this.groupId = groupId; + } + + public void setArtifactId(String artifactId) + { + if (this.artifactId != null) throwExceptionIfAlreadySet("artifactId", artifactId); + this.artifactId = artifactId; + } + + public void setIssueTrackerUrl(String issueTrackingUrl) + { + if (this.issueTrackerUrl != null) throwExceptionIfAlreadySet("issueTrackingUrl", issueTrackingUrl); + this.issueTrackerUrl = issueTrackingUrl; + } + + public void setLibraryMapping(LibraryMapping libraryMapping) + { + if (this.libraryMapping != null) throwExceptionIfAlreadySet("libraryMapping", libraryMapping); + this.libraryMapping = libraryMapping; + } + + public void setSourceUrlResolver(SourceUrlResolver sourceUrlResolver) + { + if (this.sourceUrlResolver != null) throwExceptionIfAlreadySet("sourceUrlResolver", sourceUrlResolver); + this.sourceUrlResolver = sourceUrlResolver; + if (sourceUrlResolver != null) + { + sourceUrlResolver.setRootUrl(getSourceRootUrl()); + } + } + + /** + * Tells whether full dependency management info (group id, artifact id and version) are present. + */ + public boolean isDependencyManagementInfoPresent() + { + return groupId != null && artifactId != null && version != null; + } + + /** + * Given a logical name, tells whether a given component, page or mixin is part of this + * component library. + */ + public boolean isPart(String logicalName) + { + return logicalName.startsWith(libraryMapping.libraryName + "/") || + (libraryMapping.libraryName.equals("") && logicalName.indexOf("/") < 0); + } + + /** + * Returns the JavaDoc URL for a given class or <code>null</code> if the root JavaDoc URL was + * not provided. + * @param className the fully qualified class name. + */ + public String getJavadocUrl(String className) + { + String url = null; + String baseUrl = getJavadocUrl(); + if (baseUrl != null) + { + if (!baseUrl.endsWith("/")) + { + baseUrl = baseUrl + "/"; + } + url = baseUrl + className.replace('.', '/') + ".html"; + } + return url; + } + + /** + * Returns the URL where the source of this class can be found or <code>null</code> if + * not available. This implementation delegates to {@link SourceUrlResolver} if set. + * @param className the fully qualified class name. + */ + public String getSourceUrl(String className) + { + String url = null; + if (sourceUrlResolver != null) + { + url = sourceUrlResolver.resolve(className); + } + return url; + } + + private void throwExceptionIfAlreadySet(String propertyName, Object propertyValue) + { + if (propertyValue != null) + { + throw new RuntimeException(String.format("%s already has a value of \"%s\"", propertyName, propertyValue)); + } + } + + /** + * Interface that provides the source URL for a given {@link ComponentLibraryInfo}. + */ + public static interface SourceUrlResolver + { + /** + * Returns the source URL for a given class. + * @param className the fully qualified class name. + */ + String resolve(String className); + + /** + * Sets the source root URL. This method will be invoked by {@link ComponentLibraryInfo#setSourceBrowseUrl(String)}. + */ + void setRootUrl(String url); + } + + /** + * {@link SourceUrlResolver} implementation based on Maven Java project conventions and + * GitWeb as online Git repository viewer, which Tapestry itself uses. + */ + public static class GitWebMavenSourceUrlResolver implements SourceUrlResolver + { + + private String sourceRootUrl; + + @Override + public String resolve(String className) + { + return sourceRootUrl + "/" + className.replace('.', '/') + ".java"; + } + + @Override + public void setRootUrl(String url) + { + this.sourceRootUrl = url; + } + + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/6843db06/tapestry-core/src/main/java/org/apache/tapestry5/services/LibraryMapping.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/LibraryMapping.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/LibraryMapping.java index 476c187..69e4f12 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/services/LibraryMapping.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/LibraryMapping.java @@ -1,4 +1,4 @@ -// Copyright 2006, 2010, 2011, 2012 The Apache Software Foundation +// Copyright 2006, 2010, 2011, 2012, 2014 The Apache Software Foundation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -11,7 +11,6 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - package org.apache.tapestry5.services; import org.apache.tapestry5.ioc.internal.util.InternalUtils; @@ -31,11 +30,18 @@ import org.apache.tapestry5.ioc.internal.util.InternalUtils; * <dt>base</dt> * <dd>contains base classes</dd> * </dl> + * <p> + * Since 5.4 on, a library mapping can also have a {@link ComponentLibraryInfo} to provide more + * information about itself, such as URLs (project, documentation, JavaDoc, sources) and + * coordinates for dependency management tools (group id, artifact id, version). + * </p> */ public final class LibraryMapping { public final String libraryName, rootPackage; - + + private ComponentLibraryInfo componentLibraryInfo; + /** * Identifies the root package of a library. The application has uses the library name "" (the empty string). * The special library "core" is all the built-in components. @@ -53,7 +59,7 @@ public final class LibraryMapping * @param libraryName * the unique identifier for the library. * @param rootPackage - * The root package to search for classes; sub-packages will include ".pages", ".components", etc. + * the root package to search for classes; sub-packages will include ".pages", ".components", etc. */ public LibraryMapping(String libraryName, String rootPackage) { @@ -68,6 +74,18 @@ public final class LibraryMapping this.libraryName = libraryName; this.rootPackage = rootPackage; + this.componentLibraryInfo = null; + } + + /** + * Same as {@link #LibraryMapping(String, String)}, with with an additional {@link ComponentLibraryInfo} parameter. + * @since 5.4 + */ + public LibraryMapping(String libraryName, String rootPackage, ComponentLibraryInfo componentLibraryInfo) + { + this(libraryName, rootPackage); + this.componentLibraryInfo = componentLibraryInfo; + componentLibraryInfo.setLibraryMapping(this); } /** @@ -85,10 +103,21 @@ public final class LibraryMapping { return rootPackage; } + + /** + * Returns the component library information for this library mapping. + * @return a {@link ComponentLibraryInfo}. + * @since 5.4 + */ + public ComponentLibraryInfo getComponentLibraryInfo() + { + return componentLibraryInfo; + } @Override public String toString() { return String.format("LibraryMapping[%s, %s]", libraryName, rootPackage); } + } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/6843db06/tapestry-core/src/main/resources/org/apache/tapestry5/core.properties ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/resources/org/apache/tapestry5/core.properties b/tapestry-core/src/main/resources/org/apache/tapestry5/core.properties index bda03c8..2601000 100644 --- a/tapestry-core/src/main/resources/org/apache/tapestry5/core.properties +++ b/tapestry-core/src/main/resources/org/apache/tapestry5/core.properties @@ -1,4 +1,4 @@ -# Copyright 2013 The Apache Software Foundation +# Copyright 2013-2014 The Apache Software Foundation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -127,4 +127,7 @@ private-default-confirm-message=Are you sure you want to continue? private-default-confirm-title=Confirm # See the LocalDate component -private-default-localdate-format=lll \ No newline at end of file +private-default-localdate-format=lll + +# see ComponentLibraries page +not-informed=Not informed \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/6843db06/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 new file mode 100644 index 0000000..147912c --- /dev/null +++ b/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/ComponentLibraries.tml @@ -0,0 +1,126 @@ +<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> + + <ul id="libraryList" class="list-group"> + <li t:type="Loop" t:source="libraryNames" t:value="libraryName" class="list-group-item"> + <a href="#${libraryClientId}"> + <code>${libraryName}</code> <t:if test="info">: ${info.name}</t:if> + </a> + <p t:type="If" t:test="info?.description"> + ${info.description} + </p> + </li> + </ul> + + <div id="libraries"> + + <div class="libraryInfo" t:type="Loop" t:source="libraryNames" t:value="libraryName" id="${libraryClientId}"> + + <h2><code>${libraryName}</code> <t:if test="info">: ${info.name}</t:if></h2> + + <t:if test="info"> + + <dl class="dl-horizontal"> + + <dt>Homepage</dt> + <dd> + <t:if test="info.homepageUrl" else="message:not-informed"> + <a href="${info.homepageUrl}">${info.homepageUrl}</a> + </t:if> + </dd> + + <dt>Documentation URL</dt> + <dd> + <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> + <t:if test="info.javadocUrl" else="message:not-informed"> + <a href="${info.javadocUrl}">${info.javadocUrl}</a> + </t:if> + </dd> + + <t:if test="info.dependencyManagementInfoPresent"> + <dt>Dependency information</dt> + <dd> + 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" + target="_blank"> + <em>More information at Maven Central Respository</em> + </a> + </dd> + </t:if> + + <dt>Source browse URL</dt> + <dd> + <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> + <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> + <t:if test="info.issueTrackerUrl" else="message:not-informed"> + <a href="${info.issueTrackerUrl}">${info.issueTrackerUrl}</a> + </t:if> + </dd> + + </dl> + + </t:if> + + <p t:type="If" t:test="!info">No additional information provided for <code>${libraryName}</code>.</p> + +<!-- <div t:type="Zone" t:id="pages" id="prop:libraryClientZoneClientId"> --> +<!-- </div> --> + + <div t:type="Delegate" to="componentsTable"></div> + <div t:type="Delegate" to="pagesTable"></div> + <div t:type="Delegate" to="mixinsTable"></div> + + </div> + + </div> + + <t:block id="classesTable"> + <div t:type="If" t:test="!logicalNames.empty"> + <h3>${headerName}</h3> + <table class="table table-striped table-hover table-condensed"> + <thead> + <tr> + <td>Name</td> + <td>JavaDoc URL</td> + <td>Source URL</td> + </tr> + </thead> + <tbody> + <tr t:type="Loop" t:source="logicalNames" t:value="logicalName"> + <td><code>${simpleLogicalName}</code></td> + <td><t:if test="javadocUrl" else="message:not-informed" target="_blank"> + <a href="${javadocUrl}">JavaDoc</a></t:if> + </td> + <td><t:if test="sourceUrl" else="message:not-informed" target="_blank"> + <a href="${sourceUrl}">Source</a></t:if> + </td> + </tr> + </tbody> + </table> + </div> + </t:block> + +</t:block>