Skip to content

Commit

Permalink
Ccs 4519 xref validation errors (#626)
Browse files Browse the repository at this point in the history
* UI fixes

* fix xref validation issues when bulk publish

* remove debugging code

* code clean up

* update UI on unpublishing

* refactor code
  • Loading branch information
xdavidson committed Sep 22, 2021
1 parent e728530 commit 433b3f9
Show file tree
Hide file tree
Showing 11 changed files with 107 additions and 86 deletions.
51 changes: 30 additions & 21 deletions pantheon-bundle/frontend/src/app/BulkOperationPublish.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -203,32 +203,19 @@ class BulkOperationPublish extends React.Component<IBulkOperationPublishProps, a
let hrefPart = href.slice(0, href.indexOf("?"))
let modulePath = hrefPart.slice(hrefPart.indexOf("/repositories"))
const backend = "/content" + modulePath + `/en_US/variants/${variant}/draft`
let exist = this.props.isBulkPublish ? Utils.draftExist(backend) : false
if (this.props.isBulkUnpublish) {
this.processDocuments(modulePath, formData, hdrs)

if (exist || this.props.isBulkUnpublish) {
fetch("/content" + modulePath, {
body: formData,
method: "post",
headers: hdrs
}).then(response => {
if (response.status === 201 || response.status === 200) {
this.setState({
documentsSucceeded: [...this.state.documentsSucceeded, modulePath],
bulkUpdateSuccess: this.state.bulkUpdateSuccess + 1,
}, () => {
this.calculateSuccessProgress(this.state.bulkUpdateSuccess)
}
)
} else {
Utils.draftExist(backend).then((exist) => {
if (exist) {
this.processDocuments(modulePath, formData, hdrs)
} else {
this.setState({ bulkUpdateFailure: this.state.bulkUpdateFailure + 1, documentsFailed: [...this.state.documentsFailed, modulePath] }, () => {
this.calculateFailureProgress(this.state.bulkUpdateFailure)
this.setState({ bulkUpdateWarning: this.state.bulkUpdateWarning + 1, documentsIgnored: [...this.state.documentsIgnored, modulePath] }, () => {
this.calculateWarningProgress(this.state.bulkUpdateWarning)
})
}
})
} else {
this.setState({ bulkUpdateWarning: this.state.bulkUpdateWarning + 1, documentsIgnored: [...this.state.documentsIgnored, modulePath] }, () => {
this.calculateWarningProgress(this.state.bulkUpdateWarning)
})
}
}

Expand Down Expand Up @@ -290,5 +277,27 @@ class BulkOperationPublish extends React.Component<IBulkOperationPublishProps, a
this.setState({ confirmationFailed: failed })
}
}

private processDocuments = (modulePath, formData, hdrs) => {
fetch("/content" + modulePath, {
body: formData,
method: "post",
headers: hdrs
}).then(response => {
if (response.status === 201 || response.status === 200) {
this.setState({
documentsSucceeded: [...this.state.documentsSucceeded, modulePath],
bulkUpdateSuccess: this.state.bulkUpdateSuccess + 1,
}, () => {
this.calculateSuccessProgress(this.state.bulkUpdateSuccess)
}
)
} else {
this.setState({ bulkUpdateFailure: this.state.bulkUpdateFailure + 1, documentsFailed: [...this.state.documentsFailed, modulePath] }, () => {
this.calculateFailureProgress(this.state.bulkUpdateFailure)
})
}
})
}
}
export { BulkOperationPublish }
15 changes: 8 additions & 7 deletions pantheon-bundle/frontend/src/app/Utils.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
import { resolve } from "path"

export class Utils {

/**
* fetchHelper
* @param endpoint: string
* @param options: object
*/

static fetchHelper = (endpoint: string, options: object) => {

if (options !== null) {
return fetch(endpoint, options)
.then(Utils.handleErrors)
.then(response => response.json())
.then(Utils.handleErrors)
.then(response => response.json())
} else {
return fetch(endpoint)
.then(Utils.handleErrors)
.then(response => response.json())
.then(Utils.handleErrors)
.then(response => response.json())
}
}

Expand Down Expand Up @@ -51,4 +53,3 @@ export class Utils {
})
}
}

4 changes: 3 additions & 1 deletion pantheon-bundle/frontend/src/app/bulkOperationMetadata.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ class BulkOperationMetadata extends React.Component<IBulkOperationMetadataProps,

public componentDidMount() {
// fetch products and label for metadata Modal
this.fetchProducts()
if (this.props.isEditMetadata) {
this.fetchProducts()
}
}

public render() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,7 @@ private String buildDocument(@Nonnull Document base, @Nonnull Locale locale, @No
String html = "";
try {
TableOfContents tableOfContents = new TableOfContents();
PantheonXrefProcessor xrefProcessor = new PantheonXrefProcessor(documentVariant, tableOfContents
);
PantheonXrefProcessor xrefProcessor = new PantheonXrefProcessor(documentVariant, tableOfContents);
// extensions needed to generate a module's html
asciidoctor.javaExtensionRegistry().includeProcessor(
new SlingResourceIncludeProcessor(base, tableOfContents, xrefProcessor));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.apache.sling.api.resource.Resource;
import org.asciidoctor.ast.ContentNode;
import org.asciidoctor.extension.InlineMacroProcessor;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -47,18 +48,25 @@ public class PantheonXrefProcessor extends InlineMacroProcessor {
* @param documentVariant
* @param tableOfContents Doesn't necessarily need to be populated when this constructor is called.
*/
public PantheonXrefProcessor(DocumentVariant documentVariant, TableOfContents tableOfContents) {
public PantheonXrefProcessor(@Reference DocumentVariant documentVariant, @Reference TableOfContents tableOfContents) {
this.documentVariant = documentVariant;
this.toc = tableOfContents;
}

public String preprocess(String content) {
List<String> urlList = new ArrayList<>();
HashMap<String, ArrayList<String>> xrefTargetsMap = new HashMap<>();

if (!documentVariant.getPath().startsWith("/content/docs/")) {
content = preprocessWithPattern(content, XREF_PATTERN, urlList);
content = preprocessWithPattern(content, TRIANGLE_PATTERN, urlList);
}
XrefValidationHelper.getInstance().setObjectsToValidate(urlList);

if (!urlList.isEmpty()) {
xrefTargetsMap.put(documentVariant.uuid().get(), (ArrayList<String>) urlList);
XrefValidationHelper.setObjectsToValidate(xrefTargetsMap);
}

return content;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public class DocumentVariantRenderServlet extends SlingSafeMethodsServlet {
private final Logger log = LoggerFactory.getLogger(DocumentVariantRenderServlet.class);

private AsciidoctorService asciidoctorService;
private XrefValidationHelper xrefValidationHelper;

@Activate
public DocumentVariantRenderServlet(
Expand Down Expand Up @@ -94,7 +95,7 @@ protected void doGet(SlingHttpServletRequest request,

// only allow forced rerendering if this is a draft version. Released and historical revs are written in stone.
boolean draft = latest && variant.hasDraft();
XrefValidationHelper.getInstance().initList();
XrefValidationHelper.initList();
String html = asciidoctorService.getDocumentHtml(
variant.getParentLocale().getParent(),
LocaleUtils.toLocale(variant.getParentLocale().getName()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ public void run(SlingHttpServletRequest request, PostResponse response, SlingPos
return;
}
long startTime = System.currentTimeMillis();
XrefValidationHelper.initList();
super.run(request, response, processors);
try {
if (response.getError() == null) {
Expand All @@ -101,13 +102,12 @@ public void run(SlingHttpServletRequest request, PostResponse response, SlingPos
.released().get();

// Regenerate the document once more
XrefValidationHelper.getInstance().initList();
asciidoctorService.getDocumentHtml(document, locale, variant, false, new HashMap(),true);
events.fireEvent(new DocumentVersionPublishedEvent(documentVersion), 15);
ServletUtils.getCustomerPortalUrl(request, response);
}
}catch (RepositoryException ex){
logger.error("An error has occured ", ex.getMessage());
logger.error("An error has occurred ", ex.getMessage());
}
log.debug("Operation Publishing draft version, completed");
long elapseTime = System.currentTimeMillis() - startTime;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ protected void versionUpload(SlingHttpServletRequest request,
resolver.commit();

Map<String, Object> context = asciidoctorService.buildContextFromRequest(request);
XrefValidationHelper.getInstance().initList();
XrefValidationHelper.initList();
asciidoctorService.getDocumentHtml(document, localeObj, document.getWorkspace().getCanonicalVariantName(),
true, context, true);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Optional;

/**
Expand All @@ -17,26 +19,32 @@ public class ValidationHelper {
Logger logger = LoggerFactory.getLogger(ValidationHelper.class);
public void createXrefValidationNode(DocumentVersion documentVersion, String content) throws PersistenceException {
Violations violations = new XrefValidator(documentVersion.getParent(), content).validate();
Validations validations = documentVersion.validations().getOrCreate();
if(null != validations.validationType(PantheonConstants.TYPE_XREF).get()){
try {
validations.validationType(PantheonConstants.TYPE_XREF).get().delete();
} catch (Exception e) {
logger.error("error while validation node creation",e);
}
}
// Get xrefTargetMap
HashMap<String, ArrayList<String>> xrefTargetsMap = XrefValidationHelper.getObjectsToValidate();

if(violations.hasViolations()) {
Validation validation;
ErrorDetails errorDetails = violations.get(PantheonConstants.TYPE_XREF);
if(null == errorDetails || errorDetails.length() ==0){
return;
if (xrefTargetsMap != null && xrefTargetsMap.containsKey(documentVersion.getParent().uuid().get())) {
Validations validations = documentVersion.validations().getOrCreate();
if(null != validations.validationType(PantheonConstants.TYPE_XREF).get()){
try {
validations.validationType(PantheonConstants.TYPE_XREF).get().delete();
} catch (Exception e) {
logger.error("error while validation node creation",e);
}
}
ValidationType validationType = validations.validationType(PantheonConstants.TYPE_XREF).getOrCreate();
for(int ind=0; ind< errorDetails.length();ind++) {
validation = validationType.page(ind+1).getOrCreate();
validation.setValidation(violations, ind);

if(violations.hasViolations()) {
Validation validation;
ErrorDetails errorDetails = violations.get(PantheonConstants.TYPE_XREF);
if(null == errorDetails || errorDetails.length() ==0){
return;
}
ValidationType validationType = validations.validationType(PantheonConstants.TYPE_XREF).getOrCreate();
for(int ind=0; ind< errorDetails.length();ind++) {
validation = validationType.page(ind+1).getOrCreate();
validation.setValidation(violations, ind);
}
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,25 @@

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class XrefValidationHelper {

private List<String> xRefs;
private static HashMap<String, ArrayList<String>> xRefs;

private XrefValidationHelper() {
public XrefValidationHelper() {
xRefs = new HashMap<String, ArrayList<String>>();
}

private static class SingletonHelper{
private static final XrefValidationHelper INSTANCE = new XrefValidationHelper();
}

public static XrefValidationHelper getInstance(){
return SingletonHelper.INSTANCE;
}
public List<String> getObjectsToValidate() {
public static HashMap<String, ArrayList<String>> getObjectsToValidate() {
return xRefs;
}

public void initList() {
xRefs = new ArrayList<>();
public static void initList() {
XrefValidationHelper.xRefs = new HashMap<String, ArrayList<String>>();
}

public void setObjectsToValidate(List<String> objectsToValidate) {
if(null == xRefs || objectsToValidate.isEmpty()){
return;
}
xRefs.addAll(objectsToValidate);
public static void setObjectsToValidate(HashMap<String, ArrayList<String>> objectsToValidate) {
XrefValidationHelper.xRefs = objectsToValidate;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@
import com.redhat.pantheon.validation.helper.XrefValidationHelper;
import com.redhat.pantheon.validation.model.ErrorDetails;
import com.redhat.pantheon.validation.model.Violations;
import org.apache.sling.api.resource.Resource;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jcr.RepositoryException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* This is a sample validator that
Expand Down Expand Up @@ -56,33 +57,36 @@ public Violations validate() {

private Violations checkIfXrefValid(Violations violations) {
return violations.add(PantheonConstants.TYPE_XREF,
checkXref());
checkXref(XrefValidationHelper.getObjectsToValidate()));
}

/**
* Process xrefs
*
* @return
*/
private ErrorDetails checkXref() {
private ErrorDetails checkXref(HashMap<String, ArrayList<String>> xrefTargets) {
ErrorDetails errorDetails = new ErrorDetails();
try {
List<String> xrefTargets = XrefValidationHelper.getInstance().getObjectsToValidate();
if(null == xrefTargets || xrefTargets.size()==0){
if (null == xrefTargets || xrefTargets.size() == 0) {
return errorDetails;
}
for (String xref : xrefTargets) {
if(!xref.endsWith(".adoc")) {
if(validateIfAnchor(content,xref)<1){ // If it is anchor, it has not yet validated,
errorDetails.add(xref);
for (Map.Entry mapElement : xrefTargets.entrySet()) {
ArrayList<String> targetList = (ArrayList<String>) mapElement.getValue();

for (String xref : targetList) {
if (!xref.endsWith(".adoc")) {
if (validateIfAnchor(content, xref) < 1) { // If it is anchor, it has not yet validated,
errorDetails.add(xref);
}
} else {
errorDetails.add(xref); // if it is a adoc file, it's already processed and validated
}
}else {
errorDetails.add(xref); // if it is a adoc file, it's already processed and validated
}
}
}
catch (Exception ex){
log.error("error at validation occured",ex);
log.error("error at validation occurred",ex);
}
return errorDetails;
}
Expand Down

0 comments on commit 433b3f9

Please sign in to comment.