Skip to content

Commit

Permalink
Transfer LinkInspector settings from the 'OSGi console' to the 'Grani…
Browse files Browse the repository at this point in the history
…t' console. #47
  • Loading branch information
Saldatsenka, Siarhei committed Aug 6, 2024
1 parent 4e91d46 commit 52bb47e
Show file tree
Hide file tree
Showing 8 changed files with 419 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
/**
* Validates external links via sending HEAD requests concurrently using {@link PoolingHttpClientConnectionManager}
*/
@Component(service = LinkResolver.class)
@Component(service = {LinkResolver.class, ExternalLinkResolverImpl.class})
@Designate(ocd = ExternalLinkResolverImpl.Configuration.class)
public class ExternalLinkResolverImpl implements LinkResolver {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ public class InternalLinkResolverImpl implements LinkResolver {

private String internalLinksHost;

@Reference(target = "(service.pid=com.exadel.etoolbox.linkinspector.core.services.resolvers.ExternalLinkResolverImpl)")
private LinkResolver externalLinkResolver;
@Reference
private ExternalLinkResolverImpl externalLinkResolver;

@Activate
@Modified
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,25 @@

package com.exadel.etoolbox.linkinspector.core.services.util;

import com.adobe.granite.ui.components.ds.ValueMapResource;
import com.day.cq.commons.jcr.JcrConstants;
import org.apache.commons.lang.CharEncoding;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.entity.ContentType;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.request.RequestParameter;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.wrappers.ValueMapDecorator;
import org.apache.sling.jcr.resource.api.JcrResourceConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.*;
import java.util.stream.Collectors;

public class ServletUtil {
Expand Down Expand Up @@ -68,4 +72,21 @@ public static void writeJsonResponse(SlingHttpServletResponse response, String j
LOG.error("Failed to write json to response", e);
}
}

public static Resource createTab(ResourceResolver resolver, String path, String title, Collection<Resource> children) {

Resource items = createResource(resolver, path + "/items", Collections.emptyMap(), children);

Map<String, Object> properties = new HashMap<>();
properties.put(JcrConstants.JCR_TITLE, title);
properties.put(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY, "granite/ui/components/coral/foundation/container");
return createResource(resolver, path, properties, Collections.singletonList(items));
}

public static Resource createResource(ResourceResolver resolver, String path, Map<String, Object> properties, Collection<Resource> children) {

ValueMap valueMap = new ValueMapDecorator(properties);
String resourceType = StringUtils.defaultIfEmpty(properties.getOrDefault(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY, StringUtils.EMPTY).toString(), JcrConstants.NT_UNSTRUCTURED);
return new ValueMapResource(resolver, path, resourceType, valueMap, children);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.exadel.etoolbox.linkinspector.core.servlets;

import com.adobe.granite.ui.components.ds.DataSource;
import com.adobe.granite.ui.components.ds.SimpleDataSource;
import com.exadel.etoolbox.linkinspector.api.LinkResolver;
import com.exadel.etoolbox.linkinspector.core.services.util.ServletUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.servlets.HttpConstants;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.apache.sling.jcr.resource.api.JcrResourceConstants;
import org.apache.sling.servlets.annotations.SlingServletResourceTypes;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

import javax.servlet.Servlet;
import java.util.*;

/**
* @author Sergey Soldatenko
*/
@Component(service = {Servlet.class})
@SlingServletResourceTypes(
resourceTypes = "/bin/etoolbox/link-inspector/settings/linktypes",
methods = HttpConstants.METHOD_GET)
public class LinkTypesDataSourceServlet extends SlingSafeMethodsServlet {

@Reference
private transient List<LinkResolver> linkResolvers;

@Override
protected void doGet(final SlingHttpServletRequest request, final SlingHttpServletResponse response) {

List<Resource> links = new ArrayList<>();
for (LinkResolver linkResolver : linkResolvers) {
Map<String, Object> fieldProperties = new HashMap<>();
fieldProperties.put(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY, "granite/ui/components/coral/foundation/form/checkbox");

String serviceName = linkResolver.getClass().getName();
fieldProperties.put("name", "./" + serviceName + ".linkType");
fieldProperties.put("text", StringUtils.substringAfterLast(serviceName, "."));
fieldProperties.put("fieldDescription", StringUtils.substringAfterLast(serviceName, "."));
fieldProperties.put("uncheckedValue", Boolean.FALSE);
fieldProperties.put("checked", Boolean.FALSE);
fieldProperties.put("value", Boolean.TRUE);
Resource checkBox = ServletUtil.createResource(request.getResourceResolver(), serviceName, fieldProperties, Collections.emptyList());
links.add(checkBox);
}

DataSource dataSource = new SimpleDataSource(links.iterator());
request.setAttribute(DataSource.class.getName(), dataSource);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package com.exadel.etoolbox.linkinspector.core.servlets;

/**
* @author Sergey Soldatenko
*/

import com.adobe.granite.ui.components.ds.DataSource;
import com.adobe.granite.ui.components.ds.SimpleDataSource;
import com.exadel.etoolbox.linkinspector.api.LinkResolver;
import com.exadel.etoolbox.linkinspector.core.services.util.ServletUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.servlets.HttpConstants;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.apache.sling.jcr.resource.api.JcrResourceConstants;
import org.apache.sling.servlets.annotations.SlingServletResourceTypes;
import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.metatype.AttributeDefinition;
import org.osgi.service.metatype.MetaTypeInformation;
import org.osgi.service.metatype.MetaTypeService;
import org.osgi.service.metatype.ObjectClassDefinition;

import javax.servlet.Servlet;
import java.util.*;

@Component(service = {Servlet.class})
@SlingServletResourceTypes(
resourceTypes = "/bin/etoolbox/link-inspector/settings",
methods = HttpConstants.METHOD_GET)
public class SettingsDataSourceServlet extends SlingSafeMethodsServlet {

@Reference
private transient MetaTypeService metaTypeService;

@Reference
private transient List<LinkResolver> linkResolvers;

@Override
protected void doGet(final SlingHttpServletRequest request, final SlingHttpServletResponse response) {

String rootPath = request.getRequestPathInfo().getResourcePath();
Resource mainTab = request.getResourceResolver().getResource(rootPath + "/main");
Resource advancedTab = request.getResourceResolver().getResource(rootPath + "/advanced");

List<Resource> tabs = new ArrayList<>();
tabs.add(mainTab);
tabs.add(advancedTab);

Map<String, List<AttributeDefinition>> serviceSettings = getServiceSettings();
for (Map.Entry<String, List<AttributeDefinition>> stringListEntry : serviceSettings.entrySet()) {
String serviceName = stringListEntry.getKey();
List<Resource> innerFields = new ArrayList<>();
for (AttributeDefinition attributeDefinition : stringListEntry.getValue()) {
Map<String, Object> fieldProperties = new HashMap<>();
fieldProperties.put(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY, getResourceTypeByType(attributeDefinition.getType()));

fieldProperties.put("name", "./" + serviceName + "." + attributeDefinition.getID());
fieldProperties.put("fieldLabel", attributeDefinition.getName());
fieldProperties.put("fieldDescription", attributeDefinition.getDescription());
Resource textField = ServletUtil.createResource(request.getResourceResolver(), serviceName + "." + attributeDefinition.getID(), fieldProperties, Collections.emptyList());
innerFields.add(textField);
}
Resource tab = ServletUtil.createTab(request.getResourceResolver(), serviceName, splitCamelCase(StringUtils.substringAfterLast(serviceName, ".")), innerFields);
tabs.add(tab);
}

DataSource dataSource = new SimpleDataSource(tabs.iterator());
request.setAttribute(DataSource.class.getName(), dataSource);
}

private String splitCamelCase(String s) {
return s.replaceAll(
String.format("%s|%s|%s",
"(?<=[A-Z])(?=[A-Z][a-z])",
"(?<=[^A-Z])(?=[A-Z])",
"(?<=[A-Za-z])(?=[^A-Za-z])"
),
" "
);
}

private String getResourceTypeByType(int type) {
String result;
switch (type) {
case 3:
result = "granite/ui/components/coral/foundation/form/numberfield";
break;
default:
result = "granite/ui/components/coral/foundation/form/textfield";
break;
}
return result;
}

private Map<String, List<AttributeDefinition>> getServiceSettings() {
Map<String, List<AttributeDefinition>> result = new HashMap<>();
for (LinkResolver linkResolver : linkResolvers) {
Bundle bundle = FrameworkUtil.getBundle(linkResolver.getClass());
MetaTypeInformation metaTypeInformation = metaTypeService.getMetaTypeInformation(bundle);
ObjectClassDefinition objectClassDefinition = metaTypeInformation.getObjectClassDefinition(linkResolver.getClass().getName(), null);
AttributeDefinition[] definitions = objectClassDefinition.getAttributeDefinitions(ObjectClassDefinition.ALL);

result.put(linkResolver.getClass().getName(), Arrays.asList(definitions));
}
return result;
}


}
1 change: 1 addition & 0 deletions ui.apps/src/main/content/META-INF/vault/filter.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<workspaceFilter version="1.0">
<filter root="/apps/etoolbox-link-inspector/clientlibs"/>
<filter root="/apps/etoolbox-link-inspector/components"/>
<filter root="/apps/etoolbox-link-inspector/options"/>
<filter root="/apps/etoolbox-link-inspector/nav"/>
<filter root="/apps/cq/core/content/nav/tools/etoolbox/link-inspector" mode="update"/>
</workspaceFilter>
Loading

0 comments on commit 52bb47e

Please sign in to comment.