我不知道当我写这些时,我已经把我的问题写得很好。我从那时开始学到了一些东西,所以我想我想说的是我想要有一种方法来生成在JCR中没有真正支持的“合成”节点,而是动态构建的。我最终最终决定如何做的是写一个ResourceProvider。我的具体使用情况,这是提供一个简单的方法为作者来填充通过从两个地方起源数据下拉组件:
我的灵感来自我的解决方案,主要来自于这篇文章:http://www.lucamasini.net/Home/sling-and-cq5/accessing-relational-data-as-sling-restful-urls
这是我写的大部分类。我忽略了从属性文件和REST资源读取的逻辑,因为这不是问题的关键。
@Component(
name = "DropdownResourceProvider",
label = "DropdownResourceProvider",
description = "Dropdown Resource Provider")
@Service
@Properties({
@Property(name = "service.description", value = "Dropdown Resource Provider"),
@Property(name = ResourceProvider.ROOTS, value = "/content/<app-name>/dropdown")
})
public class DropdownResourceProvider implements ResourceProvider {
private static final Logger log = LoggerFactory.getLogger(DropdownResourceProvider.class);
private String providerRoot;
private String providerRootPrefix;
protected void activate(BundleContext bundleContext, Map<?, ?> props) {
providerRoot = props.get(ROOTS).toString();
providerRootPrefix = providerRoot.concat("/");
}
@Override
public Resource getResource(ResourceResolver resourceResolver,
HttpServletRequest httpServletRequest, String path) {
return getResource(resourceResolver, path);
}
@Override
public Resource getResource(ResourceResolver resourceResolver, final String path) {
if (providerRoot.equals(path) || providerRootPrefix.equals(path)) {
log.info("path " + path + " matches this provider root folder: "
+ providerRoot);
return new SyntheticResource(resourceResolver, path, "sling:Folder");
} else {
String relativePath = path.substring(providerRootPrefix.length());
final String[] pathSegments = relativePath.split("/");
if (pathSegments.length > 0) {
String[] dropdownOptions; // will be a string array formatted like this: ["key=value","key=value"]
if (REST_SEGMENT_NAME.equalsIgnoreCase(pathSegments[0])) {
...invoke rest service based on information extracted from path segment values and build synthetic resources based on results...
dropdownOptions = ...set string array to results of rest invocation, formatted as needed...
} else if (PROPERTIES_SEGMENT_NAME.equalsIgnoreCase(pathSegments[0])) {
...read property file based on information extracted from path segment values and build synthetic resources based on results...
dropdownOptions = ...set string array to results of parsing property file, formatted as needed...
}
String propsPath = providerRootPrefix + StringUtils.join(Arrays.copyOfRange(pathSegments, 0, pathSegments.length - 1), "/");
return new SyntheticResource(resourceResolver, propsPath, "sling:Folder/" + pathSegments[pathSegments.length - 1]) {
public <T> T adaptTo(Class<T> type) {
return (T) dropdownOptions;
}
};
}
return null;
}
}
protected void deactivate() {
this.providerRoot = null;
this.providerRootPrefix = null;
}
}
这让我然后进入外的现成的下拉组件的编辑组件对话框,并设置项目加载路径,在我的资源提供者会回答的路径。你可以在下面的例子中看到,这将指向一个属性文件,其内容是允许用户从中选择的国家列表。将这些内容存储在存储库中并不是必需的,这为作者指出已知资源(属性,REST服务,无论您需要什么)提供了一种简单,动态的方式,并且可以轻松填充下拉列表,而无需构建自定义组件或无需在存储库中输入数百个项目。
不错的例子。你能分享上面例子的完整的类/代码吗? – 2015-11-02 22:12:12