This is an automated email from the ASF dual-hosted git repository.
dklco pushed a commit to branch insights-feature
in repository
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-app-cms.git
The following commit(s) were added to refs/heads/insights-feature by this push:
new 5aca671 Somewhat functional i18n and readability implementaton
5aca671 is described below
commit 5aca6713e04f70c1d012a101471f8d3c77f3026e
Author: Dan Klco <[email protected]>
AuthorDate: Thu Oct 18 11:30:26 2018 -0400
Somewhat functional i18n and readability implementaton
---
api/pom.xml | 4 +
.../org/apache/sling/cms/insights/Insight.java | 48 +++++--
.../apache/sling/cms/insights/InsightFactory.java | 6 +-
.../apache/sling/cms/insights/InsightsModel.java | 31 ++--
.../org/apache/sling/cms/insights/Message.java | 8 +-
core/pom.xml | 10 +-
.../cms/core/i18n/impl/I18NDictionaryImpl.java | 12 +-
.../sling/cms/core/i18n/impl/I18NProviderImpl.java | 156 ++++++++++-----------
.../core/insights/impl/FileInsightRequestImpl.java | 14 +-
.../cms/core/insights/impl/InsightFactoryImpl.java | 27 +++-
.../cms/core/insights/impl/InsightsWebConsole.java | 88 ++++++++++++
.../core/insights/impl/PageInsightRequestImpl.java | 18 ++-
.../core/internal/models/InsightsModelImpl.java | 74 ++++++++++
.../internal/models/ReadabilitySiteConfig.java | 8 +-
.../core/readability/impl/ReadabilityConfig.java | 16 +--
.../impl/ReadabilityInsightProvider.java | 68 +++++++--
.../main/resources/OSGI-INF/l10n/bundle.properties | 24 +++-
pom.xml | 6 +
.../resources/SLING-INF/nodetypes/nodetypes.cnd | 107 +++++++-------
.../readability.jsp => caconfig/base/base.jsp} | 3 +-
.../{caconfigs => caconfig}/readability.json | 1 +
.../caconfig/readability/config/config.jsp | 47 +++----
.../caconfig/readability/config/edit.json | 25 ++++
.../readability/include.jsp} | 11 +-
.../components/insights/insight/insight.jsp | 44 ++++++
.../insights/insightlist/insightlist.jsp | 40 ++----
.../libs/sling-cms/content/shared/insights.json | 27 ++++
.../resources/jcr_root/libs/sling-cms/i18n.json | 34 +++++
...adability.impl.ReadabilityServiceImpl.en.config | 24 ++++
29 files changed, 697 insertions(+), 284 deletions(-)
diff --git a/api/pom.xml b/api/pom.xml
index 64efe15..64255f0 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -18,6 +18,10 @@
<name>Apache Sling - CMS API</name>
<description>An API for the Apache Sling Reference CMS
Application</description>
+ <properties>
+ <sling.java.version>8</sling.java.version>
+ </properties>
+
<build>
<plugins>
<plugin>
diff --git a/api/src/main/java/org/apache/sling/cms/insights/Insight.java
b/api/src/main/java/org/apache/sling/cms/insights/Insight.java
index 41c70e1..136ff16 100644
--- a/api/src/main/java/org/apache/sling/cms/insights/Insight.java
+++ b/api/src/main/java/org/apache/sling/cms/insights/Insight.java
@@ -24,16 +24,17 @@ import java.util.List;
/**
* Simple POJO Model for holding an insight provider's results.
*/
-public class Insight {
+public class Insight implements Comparable<Insight> {
- private Object data;
private boolean display = true;
+ private Message primaryMessage;
private InsightProvider provider;
private InsightRequest request;
private double score;
private boolean scored = false;
private List<Message> scoreDetails = new ArrayList<>();
private boolean skip = false;
+
private boolean succeeded = true;
public Insight(InsightProvider provider, InsightRequest request) {
@@ -45,11 +46,21 @@ public class Insight {
scoreDetails.add(message);
}
- /**
- * @return the data
- */
- public Object getData() {
- return data;
+ @Override
+ public int compareTo(Insight o) {
+ if (o.scored && !scored) {
+ return 1;
+ } else if (!o.scored && scored) {
+ return -1;
+ } else if (o.scored && scored) {
+ return (int) (score - o.score);
+ } else {
+ return provider.getTitle().compareTo(o.getProvider().getTitle());
+ }
+ }
+
+ public Message getPrimaryMessage() {
+ return primaryMessage;
}
/**
@@ -106,19 +117,16 @@ public class Insight {
}
/**
- * @param data the data to set
- */
- public void setData(Object data) {
- this.data = data;
- }
-
- /**
* @param display the display to set
*/
public void setDisplay(boolean display) {
this.display = display;
}
+ public void setPrimaryMessage(Message primaryMessage) {
+ this.primaryMessage = primaryMessage;
+ }
+
/**
* @param provider the provider to set
*/
@@ -165,4 +173,16 @@ public class Insight {
this.succeeded = succeeded;
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "Insight [display=" + display + ", primaryMessage=" +
primaryMessage + ", provider=" + provider
+ + ", request=" + request + ", score=" + score + ", scored=" +
scored + ", scoreDetails=" + scoreDetails
+ + ", skip=" + skip + ", succeeded=" + succeeded + "]";
+ }
+
}
diff --git
a/api/src/main/java/org/apache/sling/cms/insights/InsightFactory.java
b/api/src/main/java/org/apache/sling/cms/insights/InsightFactory.java
index f7d2e9b..c500a7a 100644
--- a/api/src/main/java/org/apache/sling/cms/insights/InsightFactory.java
+++ b/api/src/main/java/org/apache/sling/cms/insights/InsightFactory.java
@@ -18,7 +18,7 @@
*/
package org.apache.sling.cms.insights;
-import java.util.Collection;
+import java.util.List;
import org.apache.sling.cms.File;
import org.apache.sling.cms.Page;
@@ -34,7 +34,7 @@ public interface InsightFactory {
* @param file the file for which to retrieve the insights
* @return the insights
*/
- Collection<Insight> getInsights(File file);
+ List<Insight> getInsights(File file);
/**
@@ -43,6 +43,6 @@ public interface InsightFactory {
* @param page the page for which to retrieve the insights
* @return the insights
*/
- Collection<Insight> getInsights(Page page);
+ List<Insight> getInsights(Page page);
}
diff --git
a/core/src/main/java/org/apache/sling/cms/core/insights/impl/FileInsightRequestImpl.java
b/api/src/main/java/org/apache/sling/cms/insights/InsightsModel.java
similarity index 58%
copy from
core/src/main/java/org/apache/sling/cms/core/insights/impl/FileInsightRequestImpl.java
copy to api/src/main/java/org/apache/sling/cms/insights/InsightsModel.java
index ce3bd85..bfe8ec0 100644
---
a/core/src/main/java/org/apache/sling/cms/core/insights/impl/FileInsightRequestImpl.java
+++ b/api/src/main/java/org/apache/sling/cms/insights/InsightsModel.java
@@ -16,31 +16,20 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.sling.cms.core.insights.impl;
+package org.apache.sling.cms.insights;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.cms.File;
-import org.apache.sling.cms.insights.FileInsightRequest;
+import java.util.List;
/**
- * Implementation of the FileInsightRequest interface
+ * A model interface for retrieving insights for the current resource
*/
-public class FileInsightRequestImpl implements FileInsightRequest {
+public interface InsightsModel {
- private File file;
-
- public FileInsightRequestImpl(File file) {
- this.file = file;
- }
-
- @Override
- public Resource getResource() {
- return file.getResource();
- }
-
- @Override
- public File getFile() {
- return file;
- }
+ /**
+ * Retrieve the insights for the current resource.
+ *
+ * @return the insights for the resource
+ */
+ List<Insight> getInsights();
}
diff --git a/api/src/main/java/org/apache/sling/cms/insights/Message.java
b/api/src/main/java/org/apache/sling/cms/insights/Message.java
index 132d86b..c3635cd 100644
--- a/api/src/main/java/org/apache/sling/cms/insights/Message.java
+++ b/api/src/main/java/org/apache/sling/cms/insights/Message.java
@@ -24,7 +24,7 @@ package org.apache.sling.cms.insights;
public class Message {
public enum STYLE {
- DANGER, DEFAULT, SUCCESS, WARN
+ DANGER, DEFAULT, SUCCESS, WARNING
}
public static Message danger(String text) {
@@ -40,7 +40,7 @@ public class Message {
}
public static Message warn(String text) {
- return new Message(text, STYLE.WARN);
+ return new Message(text, STYLE.WARNING);
}
private STYLE style;
@@ -55,11 +55,11 @@ public class Message {
public STYLE getStyle() {
return style;
}
-
+
public String getStyleClass() {
String styleClass = "";
if (style != STYLE.DEFAULT) {
- styleClass = "text-" + style.toString().toLowerCase();
+ styleClass = "is-" + style.toString().toLowerCase();
}
return styleClass;
}
diff --git a/core/pom.xml b/core/pom.xml
index f1b3683..219306d 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -16,7 +16,11 @@
<artifactId>org.apache.sling.cms.core</artifactId>
<packaging>bundle</packaging>
<name>Apache Sling - CMS Core</name>
- <description>The c for the Apache Sling Reference CMS
Application</description>
+ <description>The core for the Apache Sling Reference CMS
Application</description>
+
+ <properties>
+ <sling.java.version>8</sling.java.version>
+ </properties>
<build>
<plugins>
@@ -194,5 +198,9 @@
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.i18n</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.webconsole</artifactId>
+ </dependency>
</dependencies>
</project>
\ No newline at end of file
diff --git
a/core/src/main/java/org/apache/sling/cms/core/i18n/impl/I18NDictionaryImpl.java
b/core/src/main/java/org/apache/sling/cms/core/i18n/impl/I18NDictionaryImpl.java
index aae84f8..36ff759 100644
---
a/core/src/main/java/org/apache/sling/cms/core/i18n/impl/I18NDictionaryImpl.java
+++
b/core/src/main/java/org/apache/sling/cms/core/i18n/impl/I18NDictionaryImpl.java
@@ -40,13 +40,15 @@ public class I18NDictionaryImpl implements I18NDictionary {
public String get(String key, Object[] args) {
String localized = get(key);
- if (localized == null || args == null) {
+ if (localized == null) {
return key;
}
- for (int i = 0; i < args.length; i++) {
- Object o = args[i];
- if (o != null) {
- localized = localized.replace("{" + i + "}", o.toString());
+ if (args != null) {
+ for (int i = 0; i < args.length; i++) {
+ Object o = args[i];
+ if (o != null) {
+ localized = localized.replace("{" + i + "}", o.toString());
+ }
}
}
return localized;
diff --git
a/core/src/main/java/org/apache/sling/cms/core/i18n/impl/I18NProviderImpl.java
b/core/src/main/java/org/apache/sling/cms/core/i18n/impl/I18NProviderImpl.java
index c4e846a..32aacb7 100644
---
a/core/src/main/java/org/apache/sling/cms/core/i18n/impl/I18NProviderImpl.java
+++
b/core/src/main/java/org/apache/sling/cms/core/i18n/impl/I18NProviderImpl.java
@@ -37,34 +37,84 @@ import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.osgi.service.component.annotations.ReferencePolicyOption;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
@SuppressWarnings("deprecation")
@Component(service = I18NProvider.class)
public class I18NProviderImpl implements I18NProvider {
+ /**
+ * Provider that goes through a list of registered providers and takes the
first
+ * non-null responses
+ */
+ private class CombinedBundleProvider implements ResourceBundleProvider {
+
+ @Override
+ public Locale getDefaultLocale() {
+ // ask all registered providers, use the first one that returns
+ final ResourceBundleProvider[] sp = sortedProviders;
+ for (int i = sp.length - 1; i >= 0; i--) {
+ final ResourceBundleProvider provider = sp[i];
+ final Locale locale = provider.getDefaultLocale();
+ if (locale != null) {
+ log.trace("Found default locale {}", locale);
+ return locale;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public ResourceBundle getResourceBundle(final Locale locale) {
+ return getResourceBundle(null, locale);
+ }
+
+ @Override
+ public ResourceBundle getResourceBundle(final String baseName, final
Locale locale) {
+ log.debug("Retrieving resource bundle for {}", locale);
+ // ask all registered providers, use the first one that returns
+ final ResourceBundleProvider[] sp = sortedProviders;
+ for (int i = sp.length - 1; i >= 0; i--) {
+ final ResourceBundleProvider provider = sp[i];
+ final ResourceBundle bundle = baseName != null ?
provider.getResourceBundle(baseName, locale)
+ : provider.getResourceBundle(locale);
+ if (bundle != null) {
+ log.trace("Using bundle {}", bundle);
+ return bundle;
+ }
+ }
+ return null;
+ }
+ }
+
+ private static final Logger log =
LoggerFactory.getLogger(I18NProviderImpl.class);
private final DefaultLocaleResolver defaultLocaleResolver = new
DefaultLocaleResolver();
private volatile LocaleResolver localeResolver = defaultLocaleResolver;
- private volatile RequestLocaleResolver requestLocaleResolver =
defaultLocaleResolver;
-
private final Map<Object, ResourceBundleProvider> providers = new
TreeMap<>();
+ private volatile RequestLocaleResolver requestLocaleResolver =
defaultLocaleResolver;
+
private volatile ResourceBundleProvider[] sortedProviders = new
ResourceBundleProvider[0];
- @Override
- public I18NDictionary getDictionary(SlingHttpServletRequest request) {
- List<Locale> locales = requestLocaleResolver.resolveLocale(request);
+ @Reference(cardinality = ReferenceCardinality.OPTIONAL, policy =
ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY)
+ protected void bindLocaleResolver(final LocaleResolver resolver) {
+ this.localeResolver = resolver;
+ }
- CombinedBundleProvider cbp = new CombinedBundleProvider();
- ResourceBundle bundle = null;
- for (Locale locale : locales) {
- bundle = cbp.getResourceBundle(locale);
- if (bundle != null) {
- break;
- }
+ @Reference(cardinality = ReferenceCardinality.OPTIONAL, policy =
ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY)
+ protected void bindRequestLocaleResolver(final RequestLocaleResolver
resolver) {
+ this.requestLocaleResolver = resolver;
+ }
+
+ @Reference(service = ResourceBundleProvider.class, cardinality =
ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
+ protected void bindResourceBundleProvider(final ResourceBundleProvider
provider, final Map<String, Object> props) {
+ synchronized (this.providers) {
+
this.providers.put(ServiceUtil.getComparableForServiceRanking(props,
Order.ASCENDING), provider);
+ this.sortedProviders = this.providers.values().toArray(new
ResourceBundleProvider[this.providers.size()]);
}
- return new I18NDictionaryImpl(bundle);
}
@Override
@@ -77,9 +127,19 @@ public class I18NProviderImpl implements I18NProvider {
return new I18NDictionaryImpl(cbp.getResourceBundle(locale));
}
- @Reference(cardinality = ReferenceCardinality.OPTIONAL, policy =
ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY)
- protected void bindLocaleResolver(final LocaleResolver resolver) {
- this.localeResolver = resolver;
+ @Override
+ public I18NDictionary getDictionary(SlingHttpServletRequest request) {
+ List<Locale> locales = requestLocaleResolver.resolveLocale(request);
+
+ CombinedBundleProvider cbp = new CombinedBundleProvider();
+ ResourceBundle bundle = null;
+ for (Locale locale : locales) {
+ bundle = cbp.getResourceBundle(locale);
+ if (bundle != null) {
+ break;
+ }
+ }
+ return new I18NDictionaryImpl(bundle);
}
protected void unbindLocaleResolver(final LocaleResolver resolver) {
@@ -88,24 +148,13 @@ public class I18NProviderImpl implements I18NProvider {
}
}
- @Reference(cardinality = ReferenceCardinality.OPTIONAL, policy =
ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY)
- protected void bindRequestLocaleResolver(final RequestLocaleResolver
resolver) {
- this.requestLocaleResolver = resolver;
- }
-
protected void unbindRequestLocaleResolver(final RequestLocaleResolver
resolver) {
if (this.requestLocaleResolver == resolver) {
this.requestLocaleResolver = defaultLocaleResolver;
}
}
- @Reference(service = ResourceBundleProvider.class, cardinality =
ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
- protected void bindResourceBundleProvider(final ResourceBundleProvider
provider, final Map<String, Object> props) {
- synchronized (this.providers) {
-
this.providers.put(ServiceUtil.getComparableForServiceRanking(props,
Order.ASCENDING), provider);
- this.sortedProviders = this.providers.values().toArray(new
ResourceBundleProvider[this.providers.size()]);
- }
- }
+ // ---------- internal
-----------------------------------------------------
protected void unbindResourceBundleProvider(final ResourceBundleProvider
provider,
final Map<String, Object> props) {
@@ -115,55 +164,4 @@ public class I18NProviderImpl implements I18NProvider {
}
}
- // ---------- internal
-----------------------------------------------------
-
- /**
- * Provider that goes through a list of registered providers and takes the
first
- * non-null responses
- */
- private class CombinedBundleProvider implements ResourceBundleProvider {
-
- @Override
- public Locale getDefaultLocale() {
- // ask all registered providers, use the first one that returns
- final ResourceBundleProvider[] sp = sortedProviders;
- for (int i = sp.length - 1; i >= 0; i--) {
- final ResourceBundleProvider provider = sp[i];
- final Locale locale = provider.getDefaultLocale();
- if (locale != null) {
- return locale;
- }
- }
- return null;
- }
-
- @Override
- public ResourceBundle getResourceBundle(final Locale locale) {
- // ask all registered providers, use the first one that returns
- final ResourceBundleProvider[] sp = sortedProviders;
- for (int i = sp.length - 1; i >= 0; i--) {
- final ResourceBundleProvider provider = sp[i];
- final ResourceBundle bundle =
provider.getResourceBundle(locale);
- if (bundle != null) {
- return bundle;
- }
- }
- return null;
- }
-
- @Override
- public ResourceBundle getResourceBundle(final String baseName, final
Locale locale) {
- // ask all registered providers, use the first one that returns
- final ResourceBundleProvider[] sp = sortedProviders;
- for (int i = sp.length - 1; i >= 0; i--) {
- final ResourceBundleProvider provider = sp[i];
- final ResourceBundle bundle =
provider.getResourceBundle(baseName, locale);
- if (bundle != null) {
- return bundle;
- }
- }
- return null;
- }
- }
-
}
diff --git
a/core/src/main/java/org/apache/sling/cms/core/insights/impl/FileInsightRequestImpl.java
b/core/src/main/java/org/apache/sling/cms/core/insights/impl/FileInsightRequestImpl.java
index ce3bd85..c46b43b 100644
---
a/core/src/main/java/org/apache/sling/cms/core/insights/impl/FileInsightRequestImpl.java
+++
b/core/src/main/java/org/apache/sling/cms/core/insights/impl/FileInsightRequestImpl.java
@@ -34,13 +34,23 @@ public class FileInsightRequestImpl implements
FileInsightRequest {
}
@Override
+ public File getFile() {
+ return file;
+ }
+
+ @Override
public Resource getResource() {
return file.getResource();
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
@Override
- public File getFile() {
- return file;
+ public String toString() {
+ return "FileInsightRequestImpl [file=" + file + "]";
}
}
diff --git
a/core/src/main/java/org/apache/sling/cms/core/insights/impl/InsightFactoryImpl.java
b/core/src/main/java/org/apache/sling/cms/core/insights/impl/InsightFactoryImpl.java
index 7f63bfc..e0b8573 100644
---
a/core/src/main/java/org/apache/sling/cms/core/insights/impl/InsightFactoryImpl.java
+++
b/core/src/main/java/org/apache/sling/cms/core/insights/impl/InsightFactoryImpl.java
@@ -19,7 +19,9 @@
package org.apache.sling.cms.core.insights.impl;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -30,6 +32,7 @@ import org.apache.sling.cms.insights.Insight;
import org.apache.sling.cms.insights.InsightFactory;
import org.apache.sling.cms.insights.InsightProvider;
import org.apache.sling.cms.insights.InsightRequest;
+import org.apache.sling.engine.SlingRequestProcessor;
import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceEvent;
@@ -38,15 +41,22 @@ import org.osgi.framework.ServiceReference;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+/**
+ * Implementation of the InsightFactory service interface
+ */
@Component(immediate = true, service = { InsightFactory.class,
ServiceListener.class })
public class InsightFactoryImpl implements InsightFactory, ServiceListener {
private static final Logger log =
LoggerFactory.getLogger(InsightFactoryImpl.class);
private static final Map<String, InsightProvider> insightProviders = new
HashMap<>();
+ @Reference
+ private SlingRequestProcessor requestProcessor;
+
@Activate
public void activate(ComponentContext context) throws
InvalidSyntaxException {
log.info("activate");
@@ -80,19 +90,24 @@ public class InsightFactoryImpl implements InsightFactory,
ServiceListener {
}
@Override
- public Collection<Insight> getInsights(File file) {
+ public List<Insight> getInsights(File file) {
return getInsights(new FileInsightRequestImpl(file));
}
@Override
- public Collection<Insight> getInsights(Page page) {
- return getInsights(new PageInsightRequestImpl(page));
+ public List<Insight> getInsights(Page page) {
+ return getInsights(new PageInsightRequestImpl(page, requestProcessor));
}
- private Collection<Insight> getInsights(InsightRequest request) {
- return insightProviders.values().stream().filter(ip ->
ip.isEnabled(request))
- .map(ip ->
ip.evaluateRequest(request)).collect(Collectors.toList());
+ public Collection<InsightProvider> getProviders() {
+ return insightProviders.values();
+ }
+ private List<Insight> getInsights(InsightRequest request) {
+ List<Insight> insights = insightProviders.values().stream().filter(ip
-> ip.isEnabled(request))
+ .map(ip ->
ip.evaluateRequest(request)).collect(Collectors.toList());
+ Collections.sort(insights);
+ return insights;
}
}
diff --git
a/core/src/main/java/org/apache/sling/cms/core/insights/impl/InsightsWebConsole.java
b/core/src/main/java/org/apache/sling/cms/core/insights/impl/InsightsWebConsole.java
new file mode 100644
index 0000000..416ee29
--- /dev/null
+++
b/core/src/main/java/org/apache/sling/cms/core/insights/impl/InsightsWebConsole.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.sling.cms.core.insights.impl;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Collection;
+
+import javax.servlet.Servlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.felix.webconsole.AbstractWebConsolePlugin;
+import org.apache.felix.webconsole.WebConsoleConstants;
+import org.apache.sling.cms.insights.InsightFactory;
+import org.apache.sling.cms.insights.InsightProvider;
+import org.osgi.framework.Constants;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+
+/**
+ * Simple web console plugin for listing out the available insight provider
+ */
+@Component(property = { Constants.SERVICE_DESCRIPTION + "=Web Console Plugin
for Apache Sling CMS Insights API",
+ Constants.SERVICE_VENDOR + "=The Apache Software Foundation",
+ WebConsoleConstants.PLUGIN_LABEL + "=" +
InsightsWebConsole.CONSOLE_LABEL,
+ WebConsoleConstants.PLUGIN_TITLE + "=" +
InsightsWebConsole.CONSOLE_TITLE,
+ WebConsoleConstants.CONFIG_PRINTER_MODES + "=always",
+ WebConsoleConstants.PLUGIN_CATEGORY + "=Status" }, service = {
Servlet.class })
+public class InsightsWebConsole extends AbstractWebConsolePlugin {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4819043498961127418L;
+ public static final String CONSOLE_LABEL = "insights";
+ public static final String CONSOLE_TITLE = "Insights";
+
+ @Reference
+ private InsightFactory insightFactory;
+
+ @Override
+ public String getTitle() {
+ return CONSOLE_TITLE;
+ }
+
+ @Override
+ public String getLabel() {
+ return CONSOLE_LABEL;
+ }
+
+ @Override
+ protected void renderContent(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse)
+ throws IOException {
+ PrintWriter pw = httpServletResponse.getWriter();
+ pw.println("<div id='content' class='ui-widget'><br>");
+ pw.println("<pre>");
+ pw.println("Available Insight Providers");
+ pw.println("========================");
+
+ Collection<InsightProvider> providers = ((InsightFactoryImpl)
insightFactory).getProviders();
+
+ providers.forEach(p -> {
+ pw.println();
+ pw.println(p.getTitle() + " (" + p.getClass().getName() + ")");
+ pw.println("-------------------------------------");
+ });
+ pw.println("</pre>");
+ pw.println("</div>");
+ }
+
+}
diff --git
a/core/src/main/java/org/apache/sling/cms/core/insights/impl/PageInsightRequestImpl.java
b/core/src/main/java/org/apache/sling/cms/core/insights/impl/PageInsightRequestImpl.java
index bd3860f..eadd4cd 100644
---
a/core/src/main/java/org/apache/sling/cms/core/insights/impl/PageInsightRequestImpl.java
+++
b/core/src/main/java/org/apache/sling/cms/core/insights/impl/PageInsightRequestImpl.java
@@ -24,7 +24,6 @@ import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
-import javax.inject.Inject;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -51,13 +50,13 @@ public class PageInsightRequestImpl implements
PageInsightRequest {
private final Page page;
- @Inject
- private SlingRequestProcessor requestProcessor;
+ private final SlingRequestProcessor requestProcessor;
private final ResourceResolver resourceResolver;
- public PageInsightRequestImpl(Page page) {
+ public PageInsightRequestImpl(Page page, SlingRequestProcessor
requestProcessor) {
this.page = page;
+ this.requestProcessor = requestProcessor;
this.resourceResolver = page.getResource().getResourceResolver();
}
@@ -110,4 +109,15 @@ public class PageInsightRequestImpl implements
PageInsightRequest {
return page.getResource();
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "PageInsightRequestImpl [markupCache=" + markupCache + ",
page=" + page + ", requestProcessor="
+ + requestProcessor + ", resourceResolver=" + resourceResolver
+ "]";
+ }
+
}
diff --git
a/core/src/main/java/org/apache/sling/cms/core/internal/models/InsightsModelImpl.java
b/core/src/main/java/org/apache/sling/cms/core/internal/models/InsightsModelImpl.java
new file mode 100644
index 0000000..6f2e41e
--- /dev/null
+++
b/core/src/main/java/org/apache/sling/cms/core/internal/models/InsightsModelImpl.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.sling.cms.core.internal.models;
+
+import java.util.Collections;
+import java.util.List;
+
+import javax.annotation.PostConstruct;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.cms.CMSConstants;
+import org.apache.sling.cms.File;
+import org.apache.sling.cms.Page;
+import org.apache.sling.cms.insights.Insight;
+import org.apache.sling.cms.insights.InsightFactory;
+import org.apache.sling.cms.insights.InsightsModel;
+import org.apache.sling.models.annotations.Model;
+import org.apache.sling.models.annotations.injectorspecific.OSGiService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation of the Insights Model
+ */
+@Model(adaptables = Resource.class, adapters = InsightsModel.class)
+public class InsightsModelImpl implements InsightsModel {
+
+ private static final Logger log =
LoggerFactory.getLogger(InsightsModelImpl.class);
+
+ @OSGiService
+ private InsightFactory insightsFactory;
+
+ private List<Insight> insights;
+
+ private Resource resource;
+
+ public InsightsModelImpl(Resource resource) {
+ this.resource = resource;
+ }
+
+ @PostConstruct
+ public void init() {
+ if (CMSConstants.NT_FILE.equals(resource.getResourceType())) {
+ log.debug("Gathering file insights for resource {}", resource);
+ insights =
insightsFactory.getInsights(resource.adaptTo(File.class));
+ } else if (CMSConstants.NT_PAGE.equals(resource.getResourceType())) {
+ log.debug("Gathering page insights for resource {}", resource);
+ insights =
insightsFactory.getInsights(resource.adaptTo(Page.class));
+ } else {
+ log.debug("Insights not available for resource {}", resource);
+ insights = Collections.emptyList();
+ }
+ }
+
+ @Override
+ public List<Insight> getInsights() {
+ return insights;
+ }
+
+}
diff --git
a/core/src/main/java/org/apache/sling/cms/core/internal/models/ReadabilitySiteConfig.java
b/core/src/main/java/org/apache/sling/cms/core/internal/models/ReadabilitySiteConfig.java
index 5007857..b329e3d 100644
---
a/core/src/main/java/org/apache/sling/cms/core/internal/models/ReadabilitySiteConfig.java
+++
b/core/src/main/java/org/apache/sling/cms/core/internal/models/ReadabilitySiteConfig.java
@@ -16,6 +16,8 @@
*/
package org.apache.sling.cms.core.internal.models;
+import javax.inject.Inject;
+
import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.Model;
@@ -26,8 +28,10 @@ import org.apache.sling.models.annotations.Model;
@Model(adaptables = Resource.class)
public interface ReadabilitySiteConfig {
- double minGradeLevel();
+ @Inject
+ double getMinGradeLevel();
- double maxGradeLevel();
+ @Inject
+ double getMaxGradeLevel();
}
diff --git
a/core/src/main/java/org/apache/sling/cms/core/readability/impl/ReadabilityConfig.java
b/core/src/main/java/org/apache/sling/cms/core/readability/impl/ReadabilityConfig.java
index 5cba33f..71ea4e0 100644
---
a/core/src/main/java/org/apache/sling/cms/core/readability/impl/ReadabilityConfig.java
+++
b/core/src/main/java/org/apache/sling/cms/core/readability/impl/ReadabilityConfig.java
@@ -20,27 +20,27 @@ import
org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
/**
- * An interface for configuring the readability services for a particular
+ * An interface for configuring the %readability services for a particular
* language
*/
-@ObjectClassDefinition(name = "%config.name", description =
"%config.description", localization = "OSGI-INF/l10n/bundle")
+@ObjectClassDefinition(name = "%readability.config.name", description =
"%readability.config.description", localization = "OSGI-INF/l10n/bundle")
public @interface ReadabilityConfig {
- @AttributeDefinition(name = "%param.locale.name", description =
"%param.locale.description")
+ @AttributeDefinition(name = "%readability.param.locale.name", description
= "%readability.param.locale.description")
String locale();
- @AttributeDefinition(name = "%param.vowelexp.name", description =
"%param.vowelexp.description")
+ @AttributeDefinition(name = "%readability.param.vowelexp.name",
description = "%readability.param.vowelexp.description")
String vowelExpression();
- @AttributeDefinition(name = "%param.extravowelexp.name", description =
"%param.extravowelexp.description")
+ @AttributeDefinition(name = "%readability.param.extravowelexp.name",
description = "%readability.param.extravowelexp.description")
String extraVowelExpression();
- @AttributeDefinition(name = "%param.wordstems.name", description =
"%param.wordstems.description")
+ @AttributeDefinition(name = "%readability.param.wordstems.name",
description = "%readability.param.wordstems.description")
String[] wordstems();
- @AttributeDefinition(name = "%param.complexitymin.name", description =
"%param.complexitymin.description")
+ @AttributeDefinition(name = "%readability.param.complexitymin.name",
description = "%readability.param.complexitymin.description")
int complexityMin();
- @AttributeDefinition(name = "%param.iswordexp.name", description =
"%param.iswordexp.description")
+ @AttributeDefinition(name = "%readability.param.iswordexp.name",
description = "%readability.param.iswordexp.description")
String isWordExpression();
}
diff --git
a/core/src/main/java/org/apache/sling/cms/core/readability/impl/ReadabilityInsightProvider.java
b/core/src/main/java/org/apache/sling/cms/core/readability/impl/ReadabilityInsightProvider.java
index d15a392..47d94e2 100644
---
a/core/src/main/java/org/apache/sling/cms/core/readability/impl/ReadabilityInsightProvider.java
+++
b/core/src/main/java/org/apache/sling/cms/core/readability/impl/ReadabilityInsightProvider.java
@@ -16,6 +16,8 @@
*/
package org.apache.sling.cms.core.readability.impl;
+import java.text.DecimalFormat;
+
import org.apache.sling.api.resource.Resource;
import org.apache.sling.caconfig.resource.ConfigurationResourceResolver;
import org.apache.sling.cms.CMSConstants;
@@ -32,15 +34,23 @@ import org.apache.sling.cms.insights.Message;
import org.apache.sling.cms.insights.PageInsightRequest;
import org.apache.sling.cms.readability.ReadabilityService;
import org.apache.sling.cms.readability.ReadabilityServiceFactory;
+import org.apache.sling.cms.readability.Text;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
@Component(service = InsightProvider.class)
public class ReadabilityInsightProvider extends BaseInsightProvider {
- public static final String I18N_KEY_READABILITY_RESULT_DANGER =
"sling.cms.readability.danger";
- public static final String I18N_KEY_READABILITY_RESULT_SUCCESS =
"sling.cms.readability.success";
- public static final String I18N_KEY_READABILITY_RESULT_WARN =
"sling.cms.readability.warn";
+ public static final String I18N_KEY_READABILITY_DETAIL =
"slingcms.readability.detail";
+
+ public static final String I18N_KEY_READABILITY_RESULT_DANGER =
"slingcms.readability.danger";
+ public static final String I18N_KEY_READABILITY_RESULT_SUCCESS =
"slingcms.readability.success";
+ public static final String I18N_KEY_READABILITY_RESULT_WARN =
"slingcms.readability.warn";
+ public static final String I18N_KEY_READABILITY_STATS =
"slingcms.readability.stats";
+
+ private static final Logger log =
LoggerFactory.getLogger(ReadabilityInsightProvider.class);
public static final String READABILITY_CA_CONFIG = "readability";
@@ -53,6 +63,10 @@ public class ReadabilityInsightProvider extends
BaseInsightProvider {
@Reference
private I18NProvider i18nProvider;
+ private void addDetail(Insight insight, I18NDictionary dictionary, double
score, String title) {
+ insight.getScoreDetails().add(Message.defaultMsg(title + ": " + new
DecimalFormat("##0.00").format(score)));
+ }
+
/**
* Method for the extending classes to implement, this can safely throw
* exceptions and this will trigger a failure result to be returned.
@@ -77,6 +91,7 @@ public class ReadabilityInsightProvider extends
BaseInsightProvider {
CMSConstants.INSIGHTS_CA_CONFIG_BUCKET, READABILITY_CA_CONFIG);
ReadabilitySiteConfig config = null;
if (readabilityResource != null) {
+ log.debug("Using readability configuration {}",
readabilityResource);
config = readabilityResource.adaptTo(ReadabilitySiteConfig.class);
}
@@ -85,22 +100,42 @@ public class ReadabilityInsightProvider extends
BaseInsightProvider {
ReadabilityService svc =
factory.getReadabilityService(site.getLocale());
double score = svc.calculateAverageGradeLevel(text);
+ String scoreStr = new DecimalFormat("##0.00").format(score);
insight.setScored(true);
- if (score > config.maxGradeLevel() || score <
config.minGradeLevel()) {
+ log.debug("Calculating readability of page {}",
pageRequest.getPage());
+
+ if (score > config.getMaxGradeLevel() || score <
config.getMinGradeLevel()) {
+ log.debug("Retrieved out of bounds readability {} based on
range {}-{}", score,
+ config.getMinGradeLevel(), config.getMaxGradeLevel());
insight.setScore(0.5);
-
insight.addMessage(Message.success(dictionary.get(I18N_KEY_READABILITY_RESULT_WARN,
- new Object[] { config.minGradeLevel(),
config.maxGradeLevel(), score })));
+
insight.setPrimaryMessage(Message.warn(dictionary.get(I18N_KEY_READABILITY_RESULT_WARN,
+ new Object[] { config.getMinGradeLevel(),
config.getMaxGradeLevel(), scoreStr })));
} else {
+ log.debug("Retrieved in bounds readability {} based on range
{}-{}", score, config.getMinGradeLevel(),
+ config.getMaxGradeLevel());
insight.setScore(1.0);
-
insight.addMessage(Message.success(dictionary.get(I18N_KEY_READABILITY_RESULT_SUCCESS,
- new Object[] { config.minGradeLevel(),
config.maxGradeLevel(), score })));
+
insight.setPrimaryMessage(Message.success(dictionary.get(I18N_KEY_READABILITY_RESULT_SUCCESS,
+ new Object[] { config.getMinGradeLevel(),
config.getMaxGradeLevel(), scoreStr })));
}
+ Text t = svc.extractSentences(text);
+
+
insight.getScoreDetails().add(Message.defaultMsg(dictionary.get(I18N_KEY_READABILITY_STATS,
+ new Object[] { t.getSentences().size(), t.getWordCount(),
t.getComplexWordCount() })));
+ addDetail(insight, dictionary, svc.calculateARI(t), "ARI");
+ addDetail(insight, dictionary, svc.calculateColemanLiauIndex(t),
"Coleman-Liau Index");
+ addDetail(insight, dictionary,
svc.calculateFleschKincaidGradeLevel(t), "Flesch-Kincaid Grade Level");
+ addDetail(insight, dictionary, svc.calculateFleschReadingEase(t),
"Flesch-Kincaid Reading Ease");
+ addDetail(insight, dictionary, svc.calculateGunningFog(t),
"Gunning Fog");
+ addDetail(insight, dictionary, svc.calculateSMOG(t), "SMOG");
+
} else {
+ log.warn("Failed to get readability for resource {} site or config
were null",
+ pageRequest.getPage().getResource());
insight.setScored(false);
insight.setSucceeded(false);
-
insight.addMessage(Message.danger(dictionary.get(I18N_KEY_READABILITY_RESULT_DANGER,
+
insight.setPrimaryMessage(Message.danger(dictionary.get(I18N_KEY_READABILITY_RESULT_DANGER,
new Object[] { pageRequest.getPage().getPath() })));
}
@@ -124,7 +159,18 @@ public class ReadabilityInsightProvider extends
BaseInsightProvider {
if (smgr != null) {
site = smgr.getSite();
}
- return request.getType() == InsightRequest.TYPE.PAGE && site != null
&& site.getLocale() != null
- && factory.getReadabilityService(site.getLocale()) != null;
+ if (request.getType() != InsightRequest.TYPE.PAGE) {
+ log.debug("Insight is not of page type");
+ return false;
+ }
+ if (site == null || site.getLocale() == null) {
+ log.debug("Did not find site or locale");
+ return false;
+ }
+ if (factory.getReadabilityService(site.getLocale()) == null) {
+ log.debug("Unable to get readability service for locale {}",
site.getLocale());
+ return false;
+ }
+ return true;
}
}
diff --git a/core/src/main/resources/OSGI-INF/l10n/bundle.properties
b/core/src/main/resources/OSGI-INF/l10n/bundle.properties
index a1ca302..168dc90 100644
--- a/core/src/main/resources/OSGI-INF/l10n/bundle.properties
+++ b/core/src/main/resources/OSGI-INF/l10n/bundle.properties
@@ -87,4 +87,26 @@ pathsuggestionservlet.typeFilters.name=Type Filters
pathsuggestionservlet.typeFilters.description=The defined filters for the path
\
suggestion servlet. Each filter is provided in the format
[name]=[type1],[type2] \
Each child node of the parent resource to the provided path will be checked to
see \
-if the node is one of the provided types (or a sub-type) for the filter.
\ No newline at end of file
+if the node is one of the provided types (or a sub-type) for the filter.
+
+readability.config.name=Readability Service
+readability.config.description=A service for calculating the readability of
text using a number of different readability \
+algorithms
+
+readability.param.locale.name=Locale
+readability.param.locale.description=The locale for this configuration, should
be a valid Java Locale string
+
+readability.param.vowelexp.name=Vowel Expression
+readability.param.vowelexp.description=A regular expression for detecting
vowels within a string to denote separators for syllables
+
+readability.param.extravowelexp.name=Extra Vowel Expression
+readability.param.extravowelexp.description=A regular expression for detecting
if a word should have an additional syllable
+
+readability.param.wordstems.name=Word Stems
+readability.param.wordstems.description=An array of word stems to be stripped
from the words
+
+readability.param.complexitymin.name=Minimum Complexity
+readability.param.complexitymin.description=The minimum number of syllables
for a word to be considered complex
+
+readability.param.iswordexp.name=Is Word Expression
+readability.param.iswordexp.description=A regular expression for detecting if
a string is a word
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index d6f0146..2003a1a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -183,6 +183,12 @@
<version>2.5.14</version>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.webconsole</artifactId>
+ <version>4.2.0</version>
+ <scope>provided</scope>
+ </dependency>
</dependencies>
</dependencyManagement>
diff --git a/ui/src/main/resources/SLING-INF/nodetypes/nodetypes.cnd
b/ui/src/main/resources/SLING-INF/nodetypes/nodetypes.cnd
index a3d3731..2b33cde 100644
--- a/ui/src/main/resources/SLING-INF/nodetypes/nodetypes.cnd
+++ b/ui/src/main/resources/SLING-INF/nodetypes/nodetypes.cnd
@@ -18,70 +18,75 @@
// You can find out more documentation on this topic
// by following these links:
//
-// - http://sling.apache.org/site/content-loading.html
-// - http://jackrabbit.apache.org/node-type-notation.html
+// - http://sling.apache.org/site/content-loading.html
+// - http://jackrabbit.apache.org/node-type-notation.html
<sling = 'http://www.sling.apache.org/sling/1.0'>
-
+
[sling:Component] > nt:unstructured
- - componentType (string)
- - jcr:title (string)
-
+ - componentType (string)
+ - jcr:title (string)
+
[sling:Config] > nt:hierarchyNode
- orderable
- - sling:created (date)
- - sling:createdBy (string)
- - sling:resourceType (string)
- - jcr:lastModified (date)
- - jcr:lastModifiedBy (string)
- - jcr:title (string)
- + * (nt:unstructured) = nt:unstructured version
-
+ orderable
+ - sling:created (date)
+ - sling:createdBy (string)
+ - sling:resourceType (string)
+ - jcr:lastModified (date)
+ - jcr:lastModifiedBy (string)
+ - jcr:title (string)
+ + * (nt:unstructured) = nt:unstructured version
+ - * (UNDEFINED) multiple
+ - * (UNDEFINED)
+
[sling:File] > nt:file
- - * (undefined) copy
- + jcr:content (sling:FileContent) = sling:FileContent copy primary
autocreated
-
+ - * (undefined) copy
+ + jcr:content (sling:FileContent) = sling:FileContent copy primary
autocreated
+
[sling:FileContent] > nt:resource
- - * (undefined) copy
- - * (undefined) copy multiple
+ - * (undefined) copy
+ - * (undefined) copy multiple
[sling:Page] > nt:hierarchyNode
- orderable
- - published (boolean)
- + jcr:content (nt:unstructured) = nt:unstructured copy primary
- + * (nt:base) = nt:base version
+ orderable
+ - published (boolean)
+ + jcr:content (nt:unstructured) = nt:unstructured copy primary
+ + * (nt:base) = nt:base version
[sling:Site] > nt:hierarchyNode
- orderable
- - sling:configRef (string)
- - sling:created (date)
- - sling:createdBy (string)
- - sling:url (string)
- - jcr:language (string)
- - jcr:lastModified (date)
- - jcr:lastModifiedBy (string)
- - jcr:title (string)
- - jcr:description (string)
- + * (nt:base) = nt:base version
+ orderable
+ - sling:configRef (string)
+ - sling:created (date)
+ - sling:createdBy (string)
+ - sling:url (string)
+ - jcr:language (string)
+ - jcr:lastModified (date)
+ - jcr:lastModifiedBy (string)
+ - jcr:title (string)
+ - jcr:description (string)
+ + * (nt:base) = nt:base version
[sling:Taxonomy] > nt:hierarchyNode
- orderable
- - sling:related (string)
- - sling:created (date)
- - sling:createdBy (string)
- - jcr:lastModified (date)
- - jcr:lastModifiedBy (string)
- - jcr:title (string)
- + * (sling:Taxonomy) = sling:Taxonomy version
+ orderable
+ - sling:related (string)
+ - sling:created (date)
+ - sling:createdBy (string)
+ - jcr:lastModified (date)
+ - jcr:lastModifiedBy (string)
+ - jcr:title (string)
+ + * (sling:Taxonomy) = sling:Taxonomy version
[sling:UGC] > nt:unstructured
- approveaction (string)
- - contenttype (string)
- - finalpath (string)
- - preview (string)
- - published (boolean)
- - referrer (string)
- - user (string)
- - useragent (string)
- - userip (string)
+ - contenttype (string)
+ - finalpath (string)
+ - preview (string)
+ - published (boolean)
+ - referrer (string)
+ - user (string)
+ - useragent (string)
+ - userip (string)
+ - * (UNDEFINED) multiple
+ - * (UNDEFINED)
+
\ No newline at end of file
diff --git
a/ui/src/main/resources/jcr_root/libs/sling-cms/components/caconfigs/base/readability.jsp
b/ui/src/main/resources/jcr_root/libs/sling-cms/components/caconfig/base/base.jsp
similarity index 82%
rename from
ui/src/main/resources/jcr_root/libs/sling-cms/components/caconfigs/base/readability.jsp
rename to
ui/src/main/resources/jcr_root/libs/sling-cms/components/caconfig/base/base.jsp
index 4b2b340..bf665b4 100644
---
a/ui/src/main/resources/jcr_root/libs/sling-cms/components/caconfigs/base/readability.jsp
+++
b/ui/src/main/resources/jcr_root/libs/sling-cms/components/caconfig/base/base.jsp
@@ -21,8 +21,7 @@
<sling:call script="/libs/sling-cms/components/editor/scripts/init.jsp" />
<c:set var="oldAvailableTypes" value="${availableTypes}" />
-<c:set var="availableTypes" value="SlingCMS-FileEditor" scope="request" />
-<sling:include path="${slingRequest.requestPathInfo.suffix}"
resourceType="sling-cms/components/cms/fileeditorconfig/config" />
+<sling:call script="include.jsp" />
<c:set var="availableTypes" value="${oldAvailableTypes}" scope="request" />
<sling:call script="/libs/sling-cms/components/editor/scripts/finalize.jsp" />
diff --git
a/ui/src/main/resources/jcr_root/libs/sling-cms/components/caconfigs/readability.json
b/ui/src/main/resources/jcr_root/libs/sling-cms/components/caconfig/readability.json
similarity index 66%
rename from
ui/src/main/resources/jcr_root/libs/sling-cms/components/caconfigs/readability.json
rename to
ui/src/main/resources/jcr_root/libs/sling-cms/components/caconfig/readability.json
index 9085b01..e0f61ba 100644
---
a/ui/src/main/resources/jcr_root/libs/sling-cms/components/caconfigs/readability.json
+++
b/ui/src/main/resources/jcr_root/libs/sling-cms/components/caconfig/readability.json
@@ -1,5 +1,6 @@
{
"jcr:primaryType": "sling:Component",
"jcr:title": "Sling CMS - Readability Configuration",
+ "sling:resourceSuperType": "sling-cms/components/caconfig/base",
"componentType": "SlingCMS-Config"
}
\ No newline at end of file
diff --git
a/core/src/main/java/org/apache/sling/cms/core/insights/impl/FileInsightRequestImpl.java
b/ui/src/main/resources/jcr_root/libs/sling-cms/components/caconfig/readability/config/config.jsp
similarity index 57%
copy from
core/src/main/java/org/apache/sling/cms/core/insights/impl/FileInsightRequestImpl.java
copy to
ui/src/main/resources/jcr_root/libs/sling-cms/components/caconfig/readability/config/config.jsp
index ce3bd85..309db35 100644
---
a/core/src/main/java/org/apache/sling/cms/core/insights/impl/FileInsightRequestImpl.java
+++
b/ui/src/main/resources/jcr_root/libs/sling-cms/components/caconfig/readability/config/config.jsp
@@ -1,4 +1,4 @@
-/*
+<%-- /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -15,32 +15,19 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
- */
-package org.apache.sling.cms.core.insights.impl;
-
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.cms.File;
-import org.apache.sling.cms.insights.FileInsightRequest;
-
-/**
- * Implementation of the FileInsightRequest interface
- */
-public class FileInsightRequestImpl implements FileInsightRequest {
-
- private File file;
-
- public FileInsightRequestImpl(File file) {
- this.file = file;
- }
-
- @Override
- public Resource getResource() {
- return file.getResource();
- }
-
- @Override
- public File getFile() {
- return file;
- }
-
-}
+ */ --%>
+<%@include file="/libs/sling-cms/global.jsp"%>
+<dl>
+ <dt>
+ Min Grade Level
+ </dt>
+ <dd>
+ ${sling:encode(properties.minGradeLevel,'HTML')}
+ </dd>
+ <dt>
+ Max Grade Level
+ </dt>
+ <dd>
+ ${sling:encode(properties.maxGradeLevel,'HTML')}
+ </dd>
+</dl>
\ No newline at end of file
diff --git
a/ui/src/main/resources/jcr_root/libs/sling-cms/components/caconfig/readability/config/edit.json
b/ui/src/main/resources/jcr_root/libs/sling-cms/components/caconfig/readability/config/edit.json
new file mode 100644
index 0000000..00534c1
--- /dev/null
+++
b/ui/src/main/resources/jcr_root/libs/sling-cms/components/caconfig/readability/config/edit.json
@@ -0,0 +1,25 @@
+ {
+ "jcr:primaryType": "nt:unstructured",
+ "sling:resourceType": "sling-cms/components/editor/slingform",
+ "button": "Save Readability Configuration",
+ "fields": {
+ "jcr:primaryType": "nt:unstructured",
+ "sling:resourceType": "sling-cms/components/general/container",
+ "minGradeLevel": {
+ "jcr:primaryType": "nt:unstructured",
+ "sling:resourceType": "sling-cms/components/editor/fields/text",
+ "label": "Minimum Grade Level",
+ "name": "minGradeLevel",
+ "required": true,
+ "type": "number"
+ },
+ "maxGradeLevel": {
+ "jcr:primaryType": "nt:unstructured",
+ "sling:resourceType": "sling-cms/components/editor/fields/text",
+ "label": "Maximum Grade Level",
+ "name": "maxGradeLevel",
+ "required": true,
+ "type": "number"
+ }
+ }
+}
\ No newline at end of file
diff --git
a/ui/src/main/resources/jcr_root/libs/sling-cms/components/caconfigs/readability/readability.jsp
b/ui/src/main/resources/jcr_root/libs/sling-cms/components/caconfig/readability/include.jsp
similarity index 62%
rename from
ui/src/main/resources/jcr_root/libs/sling-cms/components/caconfigs/readability/readability.jsp
rename to
ui/src/main/resources/jcr_root/libs/sling-cms/components/caconfig/readability/include.jsp
index 4b2b340..409dc28 100644
---
a/ui/src/main/resources/jcr_root/libs/sling-cms/components/caconfigs/readability/readability.jsp
+++
b/ui/src/main/resources/jcr_root/libs/sling-cms/components/caconfig/readability/include.jsp
@@ -17,13 +17,4 @@
* under the License.
*/ --%>
<%@include file="/libs/sling-cms/global.jsp"%>
-<c:set var="cmsEditEnabled" value="true" scope="request" />
-<sling:call script="/libs/sling-cms/components/editor/scripts/init.jsp" />
-
-<c:set var="oldAvailableTypes" value="${availableTypes}" />
-<c:set var="availableTypes" value="SlingCMS-FileEditor" scope="request" />
-<sling:include path="${slingRequest.requestPathInfo.suffix}"
resourceType="sling-cms/components/cms/fileeditorconfig/config" />
-<c:set var="availableTypes" value="${oldAvailableTypes}" scope="request" />
-
-<sling:call script="/libs/sling-cms/components/editor/scripts/finalize.jsp" />
-<c:set var="cmsEditEnabled" value="false" scope="request" />
\ No newline at end of file
+<sling:include path="${slingRequest.requestPathInfo.suffix}"
resourceType="sling-cms/components/caconfig/readability/config" />
diff --git
a/ui/src/main/resources/jcr_root/libs/sling-cms/components/insights/insight/insight.jsp
b/ui/src/main/resources/jcr_root/libs/sling-cms/components/insights/insight/insight.jsp
new file mode 100644
index 0000000..f56b343
--- /dev/null
+++
b/ui/src/main/resources/jcr_root/libs/sling-cms/components/insights/insight/insight.jsp
@@ -0,0 +1,44 @@
+<%-- /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */ --%>
+<%@include file="/libs/sling-cms/global.jsp"%>
+<article class="message ${insight.primaryMessage.styleClass}">
+ <div class="message-header toggle-hidden"
data-target="#${insight.provider.id}-body">
+ <p>
+ <sling:encode value="${insight.provider.title}" mode="HTML" />
+ <c:if test="${insight.scored}">
+ <fmt:formatNumber type="percent" maxFractionDigits="2"
value="${insight.score}" />
+ </c:if>
+ </p>
+ </div>
+ <div class="message-body is-hidden" id="${insight.provider.id}-body">
+ <strong><sling:encode value="${insight.primaryMessage.text}"
mode="HTML" /></strong>
+ <c:if test="${fn:length(insight.scoreDetails) > 0}">
+ <ul>
+ <c:forEach var="detail" items="${insight.scoreDetails}">
+ <li>
+ <c:if test="${detail.style != 'DEFAULT'}">
+ <sling:encode value="${detail.style}" mode="HTML"
/> -
+ </c:if>
+ <sling:encode value="${detail.text}" mode="HTML" />
+ </li>
+ </c:forEach>
+ </ul>
+ </c:if>
+ </div>
+</article>
\ No newline at end of file
diff --git
a/core/src/main/java/org/apache/sling/cms/core/insights/impl/FileInsightRequestImpl.java
b/ui/src/main/resources/jcr_root/libs/sling-cms/components/insights/insightlist/insightlist.jsp
similarity index 57%
copy from
core/src/main/java/org/apache/sling/cms/core/insights/impl/FileInsightRequestImpl.java
copy to
ui/src/main/resources/jcr_root/libs/sling-cms/components/insights/insightlist/insightlist.jsp
index ce3bd85..71e27ff 100644
---
a/core/src/main/java/org/apache/sling/cms/core/insights/impl/FileInsightRequestImpl.java
+++
b/ui/src/main/resources/jcr_root/libs/sling-cms/components/insights/insightlist/insightlist.jsp
@@ -1,4 +1,4 @@
-/*
+<%-- /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -15,32 +15,12 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
- */
-package org.apache.sling.cms.core.insights.impl;
-
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.cms.File;
-import org.apache.sling.cms.insights.FileInsightRequest;
-
-/**
- * Implementation of the FileInsightRequest interface
- */
-public class FileInsightRequestImpl implements FileInsightRequest {
-
- private File file;
-
- public FileInsightRequestImpl(File file) {
- this.file = file;
- }
-
- @Override
- public Resource getResource() {
- return file.getResource();
- }
-
- @Override
- public File getFile() {
- return file;
- }
-
-}
+ */ --%>
+<%@include file="/libs/sling-cms/global.jsp"%>
+<sling:adaptTo var="insights"
adaptable="${slingRequest.requestPathInfo.suffixResource}"
adaptTo="org.apache.sling.cms.insights.InsightsModel" />
+<c:forEach var="in" items="${insights.insights}" varStatus="status">
+ <c:if test="${!in.skip}">
+ <c:set var="insight" value="${in}" scope="request" />
+ <sling:include path="insight-${status.index}"
resourceType="sling-cms/components/insights/insight" />
+ </c:if>
+</c:forEach>
\ No newline at end of file
diff --git
a/ui/src/main/resources/jcr_root/libs/sling-cms/content/shared/insights.json
b/ui/src/main/resources/jcr_root/libs/sling-cms/content/shared/insights.json
new file mode 100644
index 0000000..1f865e0
--- /dev/null
+++ b/ui/src/main/resources/jcr_root/libs/sling-cms/content/shared/insights.json
@@ -0,0 +1,27 @@
+{
+ "jcr:primaryType": "sling:Page",
+ "jcr:content": {
+ "sling:resourceType": "sling-cms/components/pages/base",
+ "jcr:title": "View Insights",
+ "jcr:primaryType": "nt:unstructured",
+ "container": {
+ "jcr:primaryType": "nt:unstructured",
+ "sling:resourceType": "sling-cms/components/general/container",
+ "richtext": {
+ "jcr:primaryType": "nt:unstructured",
+ "sling:resourceType": "sling-cms/components/general/richtext",
+ "text": "<h2>Content Insights</h2>"
+ },
+ "contentbreadcrumb": {
+ "jcr:primaryType": "nt:unstructured",
+ "sling:resourceType":
"sling-cms/components/cms/contentbreadcrumb",
+ "depth": 3,
+ "prefix": "/cms/site/content.html"
+ },
+ "siteconfig": {
+ "jcr:primaryType": "nt:unstructured",
+ "sling:resourceType":
"sling-cms/components/insights/insightlist"
+ }
+ }
+ }
+}
diff --git a/ui/src/main/resources/jcr_root/libs/sling-cms/i18n.json
b/ui/src/main/resources/jcr_root/libs/sling-cms/i18n.json
new file mode 100644
index 0000000..48f47f4
--- /dev/null
+++ b/ui/src/main/resources/jcr_root/libs/sling-cms/i18n.json
@@ -0,0 +1,34 @@
+{
+ "jcr:primaryType": "sling:OrderedFolder",
+ "jcr:content": {
+ "jcr:title": "Sling CMS"
+ },
+ "en_US": {
+ "jcr:primaryType": "sling:Folder",
+ "jcr:mixinTypes": [
+ "mix:language"
+ ],
+ "jcr:language": "en",
+ "sling:resourceType": "sling-cms/components/cms/blank",
+ "slingcms-readability-danger": {
+ "jcr:primaryType": "sling:MessageEntry",
+ "sling:message": "Failed to calculate readability for {1}",
+ "sling:key": "slingcms.readability.danger"
+ },
+ "slingcms-readability-stats": {
+ "jcr:primaryType": "sling:MessageEntry",
+ "sling:message": "Found {0} sentences with {1} words and {2}
complex words",
+ "sling:key": "slingcms.readability.stats"
+ },
+ "slingcms-readability-success": {
+ "jcr:primaryType": "sling:MessageEntry",
+ "sling:message": "Readability grade {2} is between expected range:
({0}-{1})",
+ "sling:key": "slingcms.readability.success"
+ },
+ "slingcms-readability-warn": {
+ "jcr:primaryType": "sling:MessageEntry",
+ "sling:message": "Readability grade {2} is outside expected range:
({0}-{1})",
+ "sling:key": "slingcms.readability.warn"
+ }
+ }
+}
\ No newline at end of file
diff --git
a/ui/src/main/resources/jcr_root/libs/sling-cms/install/org.apache.sling.cms.core.readability.impl.ReadabilityServiceImpl.en.config
b/ui/src/main/resources/jcr_root/libs/sling-cms/install/org.apache.sling.cms.core.readability.impl.ReadabilityServiceImpl.en.config
new file mode 100644
index 0000000..dd77ed5
--- /dev/null
+++
b/ui/src/main/resources/jcr_root/libs/sling-cms/install/org.apache.sling.cms.core.readability.impl.ReadabilityServiceImpl.en.config
@@ -0,0 +1,24 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+#
+locale="en"
+extraVowelExpression=".+y$"
+vowelExpression="a|e|i|o|u"
+isWordExpression="[a-zA-Z]*"
+wordstems=["es","ed","ing","e"]
+complexityMin=I"3"
\ No newline at end of file