Comparing Adobe-Consulting-Services/acs-aem-commons 53beb61..69814bc

View on GitHub
7 changed files with 216 additions and 12 deletions.
+1CHANGELOG.md
@@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com)
### Changed
- #1571 - Remove separate twitter bundle and use exception trapping to only register AdapterFactory when Twitter4J is available.
- #1573 - Tag Creator - automatic detection/support of /etc/tags or /content/cq:tags root paths
- #1578 - Asset import needs additional configuration inputs
## [3.19.0] - 2018-11-03
+5, -1bundle/pom.xml
@@ -447,6 +447,10 @@
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.testing.sling-mock.junit4</artifactId>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.testing.sling-mock</artifactId>
@@ -472,7 +476,7 @@
</dependency>
<dependency>
<groupId>io.wcm</groupId>
<artifactId>io.wcm.testing.aem-mock</artifactId>
<artifactId>io.wcm.testing.aem-mock.junit4</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
+75, -9bundle/src/main/java/com/adobe/acs/commons/mcp/impl/processes/TagCreator.java
@@ -85,7 +85,7 @@ public class TagCreator extends ProcessDefinition implements Serializable {
component = FileUploadComponent.class,
options = {"mimeTypes=application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "required"}
)
public transient InputStream tagDefinitionFile = null;
public transient InputStream excelFile = null;
@FormField(
name = "Primary Converter",
@@ -128,9 +128,16 @@ public class TagCreator extends ProcessDefinition implements Serializable {
@SuppressWarnings({"squid:S3776", "squid:S1141"})
public void parseTags(ActionManager manager) throws Exception {
manager.withResolver(rr -> {
final XSSFWorkbook workbook = new XSSFWorkbook(tagDefinitionFile);
final XSSFWorkbook workbook = new XSSFWorkbook(excelFile);
final XSSFSheet sheet = workbook.getSheetAt(0);
final Iterator<Row> rows = sheet.rowIterator();
final String tagsRootPath = new TagRootResolver(rr).getTagsLocationPath();
if (tagsRootPath == null) {
record(ReportRowSatus.FAILED_TO_PARSE,
"Abandoning Tag parsing. Unable to determine AEM Tags root (/content/cq:tags vs /etc/tags). Please ensure the path exists and is accessible by the user running Tag Creator.", "N/A", "N/A");
return;
}
while(rows.hasNext()) {
final Row row = rows.next();
@@ -150,10 +157,10 @@ public class TagCreator extends ProcessDefinition implements Serializable {
}
// Generate a tag definition that will in turn be used to drive the tag creation
TagDefinition tagDefinition = getTagDefinition(primary, cellIndex, cellValue, previousTagId);
TagDefinition tagDefinition = getTagDefinition(primary, cellIndex, cellValue, previousTagId, tagsRootPath);
if (tagDefinition == null) {
tagDefinition = getTagDefinition(fallback, cellIndex, cellValue, previousTagId);
tagDefinition = getTagDefinition(fallback, cellIndex, cellValue, previousTagId, tagsRootPath);
}
if (tagDefinition == null) {
@@ -232,11 +239,11 @@ public class TagCreator extends ProcessDefinition implements Serializable {
* @param previousTagId The previous Tag Id to build up.
* @return a valid TagDefinition, or null if a valid TagDefinition cannot be generated.
*/
private TagDefinition getTagDefinition(final TagBuilder tagBuilder, final int index, final String value, final String previousTagId) {
private TagDefinition getTagDefinition(final TagBuilder tagBuilder, final int index, final String value, final String previousTagId, final String tagsRootPath) {
final ResourceDefinitionBuilder resourceDefinitionBuilder = resourceDefinitionBuilders.get(tagBuilder.name());
if (resourceDefinitionBuilder != null && resourceDefinitionBuilder.accepts(value)) {
final TagDefinition tagDefinition = new TagDefinition(resourceDefinitionBuilder.convert(value));
final TagDefinition tagDefinition = new TagDefinition(resourceDefinitionBuilder.convert(value), tagsRootPath);
switch (index) {
case 0: tagDefinition.setId(tagDefinition.getName() + TagConstants.NAMESPACE_DELIMITER);
@@ -291,7 +298,7 @@ public class TagCreator extends ProcessDefinition implements Serializable {
CREATED,
UPDATED_EXISTING,
FAILED_TO_PARSE,
FAILED_TO_CREATE,
FAILED_TO_CREATE
}
private void record(ReportRowSatus status, String tagId, String path, String title) {
@@ -314,21 +321,80 @@ public class TagCreator extends ProcessDefinition implements Serializable {
/** Tag Definition Class **/
private final class TagDefinition extends BasicResourceDefinition {
public TagDefinition(ResourceDefinition resourceDefinition) {
private final String tagsRootPath;
public TagDefinition(ResourceDefinition resourceDefinition, String tagsRootPath) {
super(resourceDefinition.getName());
super.setId(resourceDefinition.getId());
super.setDescription(resourceDefinition.getDescription());
super.setTitle(resourceDefinition.getTitle());
super.setLocalizedTitles(resourceDefinition.getLocalizedTitles());
this.tagsRootPath = tagsRootPath;
}
@Override
public String getPath() {
if (getId() != null) {
return "/etc/tags/" + StringUtils.replace(getId(), ":", "/");
return tagsRootPath + StringUtils.replace(getId(), ":", "/");
} else {
return null;
}
}
}
protected enum TagsLocation {
ETC, CONTENT, UNKNOWN;
}
protected static final class TagRootResolver {
private static final String CONTENT_LOCATION = "/content/cq:tags";
private static final String ETC_LOCATION = "/etc/tags";
private final String tagsLocationPath;
public TagRootResolver(final ResourceResolver resourceResolver) {
final TagsLocation tagsLocation = resolveTagsLocation(resourceResolver);
if (tagsLocation == TagsLocation.CONTENT) {
tagsLocationPath = CONTENT_LOCATION;
} else if (tagsLocation == TagsLocation.ETC) {
tagsLocationPath = ETC_LOCATION;
} else if (contentLocationExists(resourceResolver)) {
tagsLocationPath = CONTENT_LOCATION;
} else if (etcLocationExists(resourceResolver)) {
tagsLocationPath = ETC_LOCATION;
} else {
tagsLocationPath = null;
}
}
public String getTagsLocationPath() {
return tagsLocationPath;
}
private TagsLocation resolveTagsLocation(ResourceResolver resourceResolver) {
final TagManager tagManager = resourceResolver.adaptTo(TagManager.class);
final Tag[] namespaces = tagManager.getNamespaces();
if (namespaces.length > 0) {
final Tag tag = namespaces[0];
if (StringUtils.startsWith(tag.getPath(), CONTENT_LOCATION)) {
return TagsLocation.CONTENT;
} else {
return TagsLocation.ETC;
}
}
return TagsLocation.UNKNOWN;
}
private boolean contentLocationExists(ResourceResolver resourceResolver) {
return resourceResolver.getResource(CONTENT_LOCATION) != null;
}
private boolean etcLocationExists(ResourceResolver resourceResolver) {
return resourceResolver.getResource(ETC_LOCATION) != null;
}
}
}
+3, -1bundle/src/test/java/com/adobe/acs/commons/data/SpreadsheetTest.java
@@ -51,6 +51,8 @@ public class SpreadsheetTest {
static XSSFWorkbook testWorkbook;
static String[] header = new String[]{"path", "title", "someOtherCol", "int-val@integer", "string-list1@string[]", "string-list2@string[;]",
"double-val@double", "array", "array", "array", "date-val@date"};
static String[] headerNames = new String[]{"path", "title", "someOtherCol", "int-val", "string-list1", "string-list2",
"double-val", "array", "array", "array", "date-val"};
static ByteArrayOutputStream workbookData = new ByteArrayOutputStream();
static Date testDate = new Date();
static Spreadsheet dataTypesSheet;
@@ -106,7 +108,7 @@ public class SpreadsheetTest {
@Test
public void testGetHeaderRow() throws IOException {
Spreadsheet instance = new Spreadsheet(false, new ByteArrayInputStream(workbookData.toByteArray()));
List<String> expResult = Arrays.asList(header);
List<String> expResult = Arrays.asList(headerNames);
List<String> result = instance.getHeaderRow();
assertTrue("Header row should match", result.containsAll(expResult));
}
+125/dev/nullbundle/src/test/java/com/adobe/acs/commons/mcp/impl/processes/TagCreatorTest.java
@@ -0,0 +1,125 @@
/*
* #%L
* ACS AEM Commons Bundle
* %%
* Copyright (C) 2018 Adobe
* %%
* 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.
* #L%
*/
package com.adobe.acs.commons.mcp.impl.processes;
import com.adobe.acs.commons.fam.ActionManager;
import com.adobe.acs.commons.functions.CheckedConsumer;
import com.adobe.acs.commons.util.datadefinitions.ResourceDefinitionBuilder;
import com.adobe.acs.commons.util.datadefinitions.impl.JcrValidNameDefinitionBuilderImpl;
import com.adobe.acs.commons.util.datadefinitions.impl.LowercaseWithDashesDefinitionBuilderImpl;
import com.adobe.acs.commons.util.datadefinitions.impl.TitleAndNodeNameDefinitionBuilderImpl;
import io.wcm.testing.mock.aem.junit.AemContext;
import org.apache.jackrabbit.JcrConstants;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.testing.mock.sling.ResourceResolverType;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doAnswer;
@RunWith(MockitoJUnitRunner.class)
public class TagCreatorTest {
@Rule
public AemContext ctx = new AemContext(ResourceResolverType.JCR_MOCK);
@Mock
private ActionManager actionManager;
private final Map<String, ResourceDefinitionBuilder> resourceDefinitionBuilders = new HashMap<>();
private TagCreator tagCreator;
@Before
public void setUp() throws Exception {
resourceDefinitionBuilders.put(AssetFolderCreator.AssetFolderBuilder.LOWERCASE_WITH_DASHES.name(), new LowercaseWithDashesDefinitionBuilderImpl());
resourceDefinitionBuilders.put(AssetFolderCreator.AssetFolderBuilder.TITLE_AND_NODE_NAME.name(), new TitleAndNodeNameDefinitionBuilderImpl());
resourceDefinitionBuilders.put(AssetFolderCreator.AssetFolderBuilder.TITLE_TO_NODE_NAME.name(), new JcrValidNameDefinitionBuilderImpl());
tagCreator = new TagCreator(resourceDefinitionBuilders);
tagCreator.excelFile = getClass().getResourceAsStream("/com/adobe/acs/commons/mcp/impl/processes/tag-creator.xlsx");
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
CheckedConsumer<ResourceResolver> method = (CheckedConsumer<ResourceResolver>) invocation.getArguments()[0];
method.accept(ctx.resourceResolver());
return null;
}
}).when(actionManager).withResolver(any(CheckedConsumer.class));
}
@Test
public void testParseAssetFolderDefinitions() throws Exception {
tagCreator.parseTags(actionManager);
final int expected = 6;
assertEquals(expected, tagCreator.tagDefinitions.size());
}
@Test
public void testCreateAssetFolders() throws Exception {
final String rootPath = "/etc/tags";
ctx.create().resource(rootPath, JcrConstants.JCR_PRIMARYTYPE, "sling:Folder");
ctx.resourceResolver().commit();
tagCreator.primary = TagCreator.TagBuilder.TITLE_AND_NODE_NAME;
tagCreator.fallback = TagCreator.TagBuilder.LOWERCASE_WITH_DASHES;
tagCreator.parseTags(actionManager);
tagCreator.importTags(actionManager);
assertTrue(ctx.resourceResolver().hasChanges());
assertEquals("Tag Namespace 1",
ctx.resourceResolver().getResource(rootPath + "/ns1").getValueMap().get("jcr:title", String.class));
assertEquals("Tag 1",
ctx.resourceResolver().getResource(rootPath + "/ns1/tag_1").getValueMap().get("jcr:title", String.class));
assertEquals("Tag 2",
ctx.resourceResolver().getResource(rootPath + "/ns1/tag-2").getValueMap().get("jcr:title", String.class));
assertEquals("Tag Namespace 2",
ctx.resourceResolver().getResource(rootPath + "/ns2").getValueMap().get("jcr:title", String.class));
assertEquals("Tag 3",
ctx.resourceResolver().getResource(rootPath + "/ns2/tag_3").getValueMap().get("jcr:title", String.class));
assertEquals("Tag 4",
ctx.resourceResolver().getResource(rootPath + "/ns2/tag-4").getValueMap().get("jcr:title", String.class));
}
}
(No newline at end of file.)
/dev/nullbundle/src/test/resources/com/adobe/acs/commons/mcp/impl/processes/tag-creator.xlsx
Binary file bundle/src/test/resources/com/adobe/acs/commons/mcp/impl/processes/tag-creator.xlsx added
+7, -1pom.xml
@@ -344,6 +344,12 @@
<version>1.7.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.testing.sling-mock.junit4</artifactId>
<version>2.3.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.testing.sling-mock</artifactId>
@@ -370,7 +376,7 @@
</dependency>
<dependency>
<groupId>io.wcm</groupId>
<artifactId>io.wcm.testing.aem-mock</artifactId>
<artifactId>io.wcm.testing.aem-mock.junit4</artifactId>
<version>2.3.2</version>
<scope>test</scope>
<exclusions>