Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
a50fe22
[EAK-605] Move ConfigDefinition to the dedicated model package
smiakchilo Oct 9, 2025
2c2af89
[EAK-605] Add "Browse" button
smiakchilo Oct 9, 2025
5885036
[EAK-605] Add more vanity paths
smiakchilo Oct 9, 2025
169b531
[EAK-605] Introduce RequestUtil
smiakchilo Oct 10, 2025
b147fbd
[EAK-605] Make PermissionUtil accept a more generic request type
smiakchilo Oct 10, 2025
ecbcd69
[EAK-605] Retire ConfigHelper; add factory logic to ConfigDefinition
smiakchilo Oct 10, 2025
7f1a6aa
[EAK-605] Add ConfigAccess enum to manage configuration access outcomes
smiakchilo Oct 10, 2025
2914b59
[EAK-605] Simplify the ConfigDataSource; add feature flags for marsha…
smiakchilo Oct 10, 2025
29cb1de
Merge branch 'develop' into feature/EAK-605-3
smiakchilo Oct 11, 2025
29f4c39
[EAK-605] Move content-related props initializing to the ConfigDefini…
smiakchilo Oct 12, 2025
90bde38
[EAK-605] Separate ResourceResolver and Session retrieval methods
smiakchilo Oct 12, 2025
4e16d6b
[EAK-605] Add necessary null checks
smiakchilo Oct 12, 2025
a4570df
[EAK-605] Introduce RefreshContainer component
smiakchilo Oct 12, 2025
bbb2131
[EAK-605] Integrate ConfigAccess into the EL expression customizer
smiakchilo Oct 12, 2025
f98b65e
[EAK-605] Introduce expression support in the alert component
smiakchilo Oct 13, 2025
40899ac
[EAK-605] Integrate ConfigDefinition into the EL expression customizer
smiakchilo Oct 13, 2025
0670a49
[EAK-605] Fix erroneous status assignment
smiakchilo Oct 13, 2025
5de0265
[EAK-605] Retire unused method
smiakchilo Oct 13, 2025
750490d
[EAK-605] Validate ConfigDefinition before building the web form data…
smiakchilo Oct 13, 2025
023f166
[EAK-605] Retire the RefreshContainer component
smiakchilo Oct 13, 2025
467c40a
[EAK-605] Switch from hidden web form fields to data attributes
smiakchilo Oct 13, 2025
54ad917
[EAK-605] Update tests to reflect changes in the code base
smiakchilo Oct 13, 2025
322367b
Merge branch 'develop' into feature/EAK-605-3
smiakchilo Oct 13, 2025
678b2c5
[EAK-617] Adjust unit tests
smiakchilo Oct 14, 2025
89e797f
[EAK-617] Simplify the web form reload logic
smiakchilo Oct 14, 2025
374eb57
[EAK-617] Reuse a method from the utility clientlib
smiakchilo Oct 14, 2025
5e4efa5
[EAK-617] Rearrange service code
smiakchilo Oct 14, 2025
edc9d2a
[EAK-617] Switch to rendering "replicable" property as data attribute
smiakchilo Oct 14, 2025
d649614
[EAK-617] Minor style change
smiakchilo Oct 14, 2025
d2f4c39
[EAK-617] Cosmetic code renaming/moving
smiakchilo Oct 14, 2025
b7760f8
[EAK-617] Add RenderConditionSupport model
smiakchilo Oct 14, 2025
8187283
[EAK-617] Cosmetic Javadoc fix
smiakchilo Oct 14, 2025
d9f89bc
[EAK-617] Add basic implementation of OSGi configurations list
smiakchilo Oct 14, 2025
daf4425
[EAK-617] Fix runtime exceptions when processing render expressions/c…
smiakchilo Oct 14, 2025
c2b1b98
[EAK-617] Minor refactoring of ConfigDefinition; rename "id"->"pid" t…
smiakchilo Oct 15, 2025
c3aa85e
[EAK-617] Add support for non-fqdn configuration PIDs
smiakchilo Oct 15, 2025
9522703
[EAK-617] Add clientlib to the console page conditionally
smiakchilo Oct 15, 2025
711bebe
[EAK-617] Modify accessors to allow package-level mutability
smiakchilo Oct 15, 2025
1d9dae9
[EAK-617] Introduce the ConfigList Sling model
smiakchilo Oct 15, 2025
610ccd4
[EAK-617] Distinguish between clientlibs for the list and webform view
smiakchilo Oct 15, 2025
af2f43a
[EAK-617] Move Sling models to the "internal" subpackage
smiakchilo Oct 15, 2025
16f77a7
[EAK-617] Limit access to the configs list by path
smiakchilo Oct 15, 2025
bad8eb4
[EAK-617] Limit access to the configs list by path
smiakchilo Oct 15, 2025
d5f3b70
Merge remote-tracking branch 'origin/feature/EAK-617' into feature/EA…
smiakchilo Oct 15, 2025
e051fcc
[EAK-617] Fix a wrong PID used to determine a factory config instance
smiakchilo Oct 15, 2025
83a3db1
[EAK-617] Fix exception being logged when an EL object is not found i…
smiakchilo Oct 15, 2025
eb6b92d
[EAK-617] Create unit tests for the ConfigDefinition model
smiakchilo Oct 15, 2025
cca95b4
[EAK-617] Simplify console output for the tests
smiakchilo Oct 15, 2025
b66a2b8
[EAK-617] Fix test terminating prematurely
smiakchilo Oct 15, 2025
8f81c45
[EAK-617] Log a PathNotFoundException
smiakchilo Oct 15, 2025
c0b2904
[EAK-617] Change display for a factory config
smiakchilo Oct 16, 2025
aa10e4b
[EAK-617] Fix display of the config list in AEM 6.5
smiakchilo Oct 16, 2025
bc90cb2
[EAK-617] Introduce common styles clientlib for the Configurator console
smiakchilo Oct 16, 2025
71c9ecb
[EAK-617] Fix checkbox events not processed in AEM 6.5
smiakchilo Oct 16, 2025
07512a8
[EAK-617] Allow "All configurations" link in the "invalid config" screen
smiakchilo Oct 16, 2025
73be3b7
[EAK-617] Cosmetic wording change
smiakchilo Oct 16, 2025
0610f42
[EAK-617] Optimize config list rendering
smiakchilo Oct 16, 2025
553829b
[EAK-617] Restore a temporarily deleted file
smiakchilo Oct 18, 2025
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
2 changes: 2 additions & 0 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@
</Import-Package>
<Sling-Model-Packages>
com.exadel.aem.toolkit.core.authoring.models,
com.exadel.aem.toolkit.core.configurator.models,
com.exadel.aem.toolkit.core.lists.models,
com.exadel.aem.toolkit.core.policymanagement.models
</Sling-Model-Packages>
<Export-Package>
com.exadel.aem.toolkit.api.*,
com.exadel.aem.toolkit.core.authoring.models,
com.exadel.aem.toolkit.core.injectors.*,
com.exadel.aem.toolkit.core.configurator.models.*,
com.exadel.aem.toolkit.core.lists.models.*,
com.exadel.aem.toolkit.core.lists.utils,
</Export-Package>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* 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 com.exadel.aem.toolkit.core.authoring.models;

import java.util.Locale;

import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.OSGiService;
import org.apache.sling.models.annotations.injectorspecific.SlingObject;
import com.adobe.granite.ui.components.ExpressionResolver;

import com.exadel.aem.toolkit.api.annotations.injectors.RequestAttribute;

/**
* Provides Granite EL expression resolver for using in HTL scripts
*/
@Model(adaptables = SlingHttpServletRequest.class)
public class ExpressionSupport {

@SlingObject
private SlingHttpServletRequest request;

@RequestAttribute
private String property;

@OSGiService
private ExpressionResolver expressionResolver;

/**
* Gets the resolved value of the property specified in the {@code property} request attribute
* @return The resolved string value
*/
public String getValue() {
String expression = StringUtils.isNotEmpty(property)
? request.getResource().getValueMap().get(property, String.class)
: null;
if (StringUtils.isEmpty(expression) || expressionResolver == null) {
return StringUtils.EMPTY;
}
try {
return expressionResolver.resolve(expression, Locale.getDefault(), String.class, request);
} catch (Exception e) {
return StringUtils.EMPTY;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* 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 com.exadel.aem.toolkit.core.authoring.models;

import java.io.IOException;
import javax.servlet.ServletException;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.SlingObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.adobe.granite.ui.components.rendercondition.RenderConditionHelper;

/**
* Provides Granite render condition support for using in HTL scripts
*/
@Model(adaptables = SlingHttpServletRequest.class)
public class RenderConditionSupport {

private static final Logger LOG = LoggerFactory.getLogger(RenderConditionSupport.class);

@SlingObject
private SlingHttpServletRequest request;

@SlingObject
private SlingHttpServletResponse response;

/**
* Checks the render condition associated with the current resource
* @return True or false
*/
public boolean check() {
RenderConditionHelper helper = new RenderConditionHelper(request, response);
try {
return helper.getRenderCondition(request.getResource()).check();
} catch (ServletException | IOException e) {
LOG.error("Render condition check failed", e);
}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/*
* 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 com.exadel.aem.toolkit.core.configurator.models.internal;

import java.util.Objects;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.adobe.granite.ui.components.ExpressionCustomizer;

import com.exadel.aem.toolkit.core.configurator.services.ConfigChangeListener;
import com.exadel.aem.toolkit.core.configurator.utils.PermissionUtil;
import com.exadel.aem.toolkit.core.configurator.utils.RequestUtil;

/**
* Enumerates possible outcomes of a configuration access request
* <p><u>Note</u>: This class is not a part of the public API and is subject to change. Do not use it in your own code
*/
public enum ConfigAccess {

GRANTED(null),

DISABLED("This tool is disabled in OSGi configuration"),
FACTORY_CONFIG("Factory configs are currently not supported"),
INVALID_CONFIG("Configuration is missing or invalid"),
NO_ACCESS("You don't have access to this feature"),
NO_CONFIG("No configuration specified"),
OSGI_FAILURE("Could not acquire OSGi entity");

private static final Logger LOG = LoggerFactory.getLogger(ConfigAccess.class);

private static final String KEY = "configAccess";

private final String error;

/**
* Default (instantiation-restricting) constructor
* @param error Error message; null if access is granted
*/
ConfigAccess(String error) {
this.error = error;
}

/**
* Gets the error message associated with this access result
* @return String value; null if access is granted
*/
public String getError() {
return error;
}

/**
* Indicates whether access is granted
* @return True or false
*/
public boolean isGranted() {
return StringUtils.isEmpty(error);
}

/**
* Determines the access result for the current request; caches the result in the request attribute for future
* reference
* @param request The current request
* @return The access result
*/
public static ConfigAccess from(HttpServletRequest request) {
if (request == null) {
return OSGI_FAILURE;
}

ExpressionCustomizer customizer = ExpressionCustomizer.from(request);
ConfigAccess result = (ConfigAccess) customizer.getVariable(KEY);
if (result != null) {
return result;
}
result = pick(request);
customizer.setVariable(KEY, result);
return result;
}

/**
* Determines the access result for the current request
* @param request The current request
* @return The access result
*/
private static ConfigAccess pick(HttpServletRequest request) {
if (!PermissionUtil.hasModifyPermission(request)) {
return NO_ACCESS;
}

String configId = RequestUtil.getConfigPid(request);
if (StringUtils.isEmpty(configId)) {
return request.getRequestURI().contains("/etoolbox/config")
&& PermissionUtil.hasGlobalModifyPermission(request) ? GRANTED : NO_CONFIG;
}

try {
BundleContext context = Objects.requireNonNull(FrameworkUtil.getBundle(ConfigAccess.class).getBundleContext());
ConfigChangeListener listener = Objects.requireNonNull(context.getService(context.getServiceReference(ConfigChangeListener.class)));
if (!listener.isEnabled()) {
return DISABLED;
}
} catch (RuntimeException e) {
LOG.error(OSGI_FAILURE.getError(), e);
return OSGI_FAILURE;
}

ConfigDefinition config = ConfigDefinition.from(request);
if (!config.isValid()) {
return INVALID_CONFIG;
}

if (config.isFactory()) {
return FACTORY_CONFIG;
}

return GRANTED;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.exadel.aem.toolkit.core.configurator.servlets;
package com.exadel.aem.toolkit.core.configurator.models.internal;

import org.apache.commons.lang3.ArrayUtils;
import org.osgi.service.metatype.AttributeDefinition;
Expand All @@ -20,9 +20,10 @@

/**
* Represents a configuration attribute, i.e., a pair of {@link AttributeDefinition} and its value
* <p><b>Note</b>: This class is not a part of the public API and is subject to change. Do not use it in your own code
* @see ConfigDefinition
*/
class ConfigAttribute {
public class ConfigAttribute {
private final AttributeDefinition definition;
private final Object value;

Expand All @@ -31,7 +32,7 @@ class ConfigAttribute {
* @param definition The attribute definition
* @param value The attribute value
*/
ConfigAttribute(AttributeDefinition definition, Object value) {
public ConfigAttribute(AttributeDefinition definition, Object value) {
this.definition = definition;
this.value = value;
}
Expand Down
Loading