Bug 569634: Add support for multiple URLs in package description
Change-Id: Ie5316eedc652d26990102f0364b291ec0f3f111f
diff --git a/rhelp/org.eclipse.statet.rhelp.core/src/org/eclipse/statet/internal/rhelp/core/SerUtil.java b/rhelp/org.eclipse.statet.rhelp.core/src/org/eclipse/statet/internal/rhelp/core/SerUtil.java
index 7d56952..3dc0d2a 100644
--- a/rhelp/org.eclipse.statet.rhelp.core/src/org/eclipse/statet/internal/rhelp/core/SerUtil.java
+++ b/rhelp/org.eclipse.statet.rhelp.core/src/org/eclipse/statet/internal/rhelp/core/SerUtil.java
@@ -49,6 +49,7 @@
@NonNullByDefault
public class SerUtil {
+ // TODO in next ser version: replace urlString by url list
public static final int VERSION_12= 12;
public static final int VERSION_11= 11;
@@ -447,6 +448,7 @@
return pkg;
}
+
private void savePkgDescription(final RPkgDescription pkgDescription,
final DataStream out) throws IOException {
out.writeString(pkgDescription.getName());
@@ -455,7 +457,7 @@
out.writeString(pkgDescription.getDescription());
out.writeString(pkgDescription.getAuthor());
out.writeString(pkgDescription.getMaintainer());
- out.writeString(pkgDescription.getUrl());
+ out.writeString(joinUrls(pkgDescription.getUrls()));
out.writeString(pkgDescription.getBuilt());
out.writeString(pkgDescription.getLibLocation().getDirectory());
}
@@ -468,17 +470,31 @@
final String description= in.readNonNullString();
final String author= in.readString();
final String maintainer= in.readString();
- final String url= in.readString();
+ final ImList<String> urls= splitUrls(in.readString());
final String built= in.readNonNullString();
final RLibLocation libLocation= getLibLocationSafe(rEnvConfig, in.readNonNullString());
return new BasicRPkgDescription(name, RNumVersion.create(version),
title, description,
author, maintainer,
- url,
+ urls,
built, libLocation);
}
+ private @Nullable String joinUrls(final List<String> urls) {
+ if (urls.isEmpty()) {
+ return null;
+ }
+ return String.join(",", urls); //$NON-NLS-1$
+ }
+
+ private ImList<String> splitUrls(final @Nullable String urlString) {
+ if (urlString == null) {
+ return ImCollections.emptyList();
+ }
+ return ImCollections.newList(urlString.split(",")); //$NON-NLS-1$
+ }
+
private RLibLocation getLibLocationSafe(final REnvHelpConfiguration rEnvConfig, final String directory) {
RLibLocation libLocation= rEnvConfig.getRLibLocationByDirectory(directory);
if (libLocation == null) {
@@ -487,6 +503,7 @@
return libLocation;
}
+
private void savePage(final RHelpPage page, final DataStream out)
throws IOException {
if (out.getVersion() >= VERSION_12) {
diff --git a/rhelp/org.eclipse.statet.rhelp.core/src/org/eclipse/statet/internal/rhelp/core/index/REnvIndexWriter.java b/rhelp/org.eclipse.statet.rhelp.core/src/org/eclipse/statet/internal/rhelp/core/index/REnvIndexWriter.java
index 26f6d55..b0523fb 100644
--- a/rhelp/org.eclipse.statet.rhelp.core/src/org/eclipse/statet/internal/rhelp/core/index/REnvIndexWriter.java
+++ b/rhelp/org.eclipse.statet.rhelp.core/src/org/eclipse/statet/internal/rhelp/core/index/REnvIndexWriter.java
@@ -202,18 +202,19 @@
private final NameField packageField= new NameField(PACKAGE_FIELD_NAME);
private final NameField pageField= new NameField(PAGE_FIELD_NAME);
private final TxtField titleTxtField= new TxtField(TITLE_TXT_FIELD_NAME);
- private final MultiValueFieldList<NameField> aliasFields= MultiValueFieldList.forNameField(
- ALIAS_FIELD_NAME );
- private final MultiValueFieldList<TxtField> aliasTxtFields= MultiValueFieldList.forTxtField(
- ALIAS_TXT_FIELD_NAME );
+ private final MultiValueFieldList<NameField> aliasFields=
+ MultiValueFieldList.forNameField(ALIAS_FIELD_NAME);
+ private final MultiValueFieldList<TxtField> aliasTxtFields=
+ MultiValueFieldList.forTxtField(ALIAS_TXT_FIELD_NAME);
private final TxtField descriptionTxtField= new TxtField(DESCRIPTION_TXT_FIELD_NAME);
private final TxtField authorsTxtField= new TxtField(AUTHORS_TXT_FIELD_NAME);
private final TxtField maintainerTxtField= new TxtField(MAINTAINER_TXT_FIELD_NAME);
- private final TxtField urlTxtField= new TxtField(URL_TXT_FIELD_NAME);
- private final MultiValueFieldList<KeywordField> keywordTxtFields= MultiValueFieldList.forKeywordField(
- KEYWORD_FIELD_NAME );
- private final MultiValueFieldList<TxtField> conteptTxtFields= MultiValueFieldList.forTxtField(
- CONCEPT_TXT_FIELD_NAME );
+ private final MultiValueFieldList<TxtField> urlTxtFields=
+ MultiValueFieldList.forTxtField(URL_TXT_FIELD_NAME);
+ private final MultiValueFieldList<KeywordField> keywordTxtFields=
+ MultiValueFieldList.forKeywordField(KEYWORD_FIELD_NAME);
+ private final MultiValueFieldList<TxtField> conteptTxtFields=
+ MultiValueFieldList.forTxtField(CONCEPT_TXT_FIELD_NAME);
private final TxtField docTxtField= new TxtField(DOC_TXT_FIELD_NAME);
private final TxtField.OmitNorm docHtmlField= new TxtField.OmitNorm(DOC_HTML_FIELD_NAME);
private final TxtField examplesTxtField= new TxtField(EXAMPLES_TXT_FIELD_NAME);
@@ -242,9 +243,12 @@
this.maintainerTxtField.setStringValue(item.getMaintainer());
doc.add(this.maintainerTxtField);
}
- if (item.getUrl() != null) {
- this.urlTxtField.setStringValue(item.getUrl());
- doc.add(this.urlTxtField);
+ { final ImList<String> urls= item.getUrls();
+ for (int i= 0; i < urls.size(); i++) {
+ final TxtField txtField= this.urlTxtFields.get(i);
+ txtField.setStringValue(urls.get(i));
+ doc.add(txtField);
+ }
}
REnvIndexWriter.this.luceneWriter.addDocument(doc);
}
diff --git a/rhelp/org.eclipse.statet.rhelp.core/src/org/eclipse/statet/rhelp/core/http/RHelpHttpServlet.java b/rhelp/org.eclipse.statet.rhelp.core/src/org/eclipse/statet/rhelp/core/http/RHelpHttpServlet.java
index 10f852f..24fa4ba 100644
--- a/rhelp/org.eclipse.statet.rhelp.core/src/org/eclipse/statet/rhelp/core/http/RHelpHttpServlet.java
+++ b/rhelp/org.eclipse.statet.rhelp.core/src/org/eclipse/statet/rhelp/core/http/RHelpHttpServlet.java
@@ -31,6 +31,7 @@
import java.nio.file.Path;
import java.util.Collections;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -247,8 +248,8 @@
@Override
protected void doGet(final HttpServletRequest req, final HttpServletResponse resp)
throws ServletException, IOException {
- final String path= req.getPathInfo();
try {
+ final String path= req.getPathInfo();
if (path != null) {
if (path.startsWith('/' + IMAGES + '/')) {
processImage(path.substring(IMAGES.length() + 2), req, resp);
@@ -512,11 +513,11 @@
writer.println("div.toc a { text-decoration: none; color: black; }"); //$NON-NLS-1$
writer.println("div.toc a:visited { text-decoration: none; color: black; }"); //$NON-NLS-1$
- writer.println("a.action { text-decoration: none; }");
- writer.println("a.action small { padding-left: 1px; padding-right: 1px; }");
- writer.println("a.action:hover small { background-color: lightgrey; color: black; }");
+ writer.println("a.action { text-decoration: none; }"); //$NON-NLS-1$
+ writer.println("a.action small { padding-left: 1px; padding-right: 1px; }"); //$NON-NLS-1$
+ writer.println("a.action:hover small { background-color: lightgrey; color: black; }"); //$NON-NLS-1$
- writer.println("img.icon { vertical-align: text-top; padding-top: 1px; padding-right: 2px; margin-right: 2px; }");
+ writer.println("img.icon { vertical-align: text-top; padding-top: 1px; padding-right: 2px; margin-right: 2px; }"); //$NON-NLS-1$
customizeCss(writer);
}
@@ -585,7 +586,7 @@
writer.write("</title>"); //$NON-NLS-1$
writer.write("<link rel=\"stylesheet\" type=\"text/css\" href=\""); //$NON-NLS-1$
writer.write(getServletPath(req)
- .append("/R.css")
+ .append("/R.css") //$NON-NLS-1$
.toString() );
writer.println("\"/>"); //$NON-NLS-1$
return writer;
@@ -824,15 +825,28 @@
printSaveHtml(writer, pkgDescription.getMaintainer());
writer.write("</td>"); //$NON-NLS-1$
}
- if (pkgDescription.getUrl() != null && pkgDescription.getUrl().length() > 0) {
+ final ImList<String> urls= pkgDescription.getUrls();
+ if (!urls.isEmpty()) {
writer.write("<tr><td>URL:</td>"); //$NON-NLS-1$
- writer.write("<td><a href=\""); //$NON-NLS-1$
- printSaveHtml(writer, pkgDescription.getUrl());
- writer.write("\"><code>"); //$NON-NLS-1$
- printSaveHtml(writer, pkgDescription.getUrl());
- writer.write("</code></a></td>"); //$NON-NLS-1$
+ writer.write("<td>"); //$NON-NLS-1$
+ for (final Iterator<String> iter= urls.iterator();;) {
+ final String url= iter.next();
+ writer.write("<a href=\""); //$NON-NLS-1$
+ printSaveHtml(writer, url);
+ writer.write("\"><code>"); //$NON-NLS-1$
+ printSaveHtml(writer, url);
+ writer.write("</code></a>"); //$NON-NLS-1$
+ if (iter.hasNext()) {
+ writer.write(", "); //$NON-NLS-1$
+ continue;
+ }
+ else {
+ break;
+ }
+ }
+ writer.write("</td>"); //$NON-NLS-1$
}
- writer.write("</table>");
+ writer.write("</table>"); //$NON-NLS-1$
}
writer.write("<p><a href=\"description\">DESCRIPTION file</a></p>"); //$NON-NLS-1$
diff --git a/rhelp/org.eclipse.statet.rhelp.core/src/org/eclipse/statet/rhelp/core/update/REnvIndexUpdater.java b/rhelp/org.eclipse.statet.rhelp.core/src/org/eclipse/statet/rhelp/core/update/REnvIndexUpdater.java
index f5f7b99..6767ff0 100644
--- a/rhelp/org.eclipse.statet.rhelp.core/src/org/eclipse/statet/rhelp/core/update/REnvIndexUpdater.java
+++ b/rhelp/org.eclipse.statet.rhelp.core/src/org/eclipse/statet/rhelp/core/update/REnvIndexUpdater.java
@@ -28,7 +28,10 @@
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.eclipse.statet.jcommons.collections.ImCollections;
+import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.status.ErrorStatus;
@@ -95,8 +98,8 @@
final String name;
- final RNumVersion version;
- final String built;
+ final @Nullable RNumVersion version;
+ final @Nullable String built;
final RLibLocation libLocation;
final RLibLocationInfo libLocationInfo; // for error messages
@@ -501,44 +504,58 @@
protected abstract IndexJob scheduleIndexJob(final String name);
+
+ private static final Pattern URL_SPLIT_PATTERN= Pattern.compile("(?:,|\\s)+"); //$NON-NLS-1$
+
private RPkgDescription createDescription(final PkgTask task) throws Exception {
final RCharacterStore data= RDataUtils.checkLengthEqual(task.rDescr.getData(), PKG_DESCR_LENGTH);
final RNumVersion version;
- final String built;
{ final String versionString= RDataUtils.checkValue(data, PKG_DESCR_IDX_VERSION);
- if (task.version != null) {
- if (!task.version.toString().equals(versionString)) {
+ final RNumVersion taskVersion= task.version;
+ if (taskVersion != null) {
+ if (!taskVersion.toString().equals(versionString)) {
throw new Exception(
String.format("Unexpected package version: expected=%1$s, found=%2$s",
- task.version, versionString ));
+ taskVersion, versionString ));
}
- version= task.version;
+ version= taskVersion;
}
else {
version= RNumVersion.create(versionString);
}
}
+ final String built;
{ final String builtString= RDataUtils.checkValue(data, PKG_DESCR_IDX_BUILT);
- if (task.built != null) {
- if (!task.built.equals(builtString)) {
+ final String taskBuilt= task.built;
+ if (taskBuilt != null) {
+ if (!taskBuilt.equals(builtString)) {
throw new Exception(
String.format("Unexpected package built: expected=%1$s, found=%2$s",
- task.built, builtString ));
+ taskBuilt, builtString ));
}
- built= task.built;
+ built= taskBuilt;
}
else {
built= builtString;
}
}
+ final ImList<String> urls;
+ { String urlString= data.get(PKG_DESCR_IDX_URL);
+ if (urlString != null && !(urlString= urlString.strip()).isEmpty()) {
+ urls= ImCollections.newList(URL_SPLIT_PATTERN.split(urlString));
+ }
+ else {
+ urls= ImCollections.emptyList();
+ }
+ }
return new BasicRPkgDescription(task.name,
version,
RDataUtils.getValue(data, PKG_DESCR_IDX_TITLE, ""), //$NON-NLS-1$
RDataUtils.getValue(data, PKG_DESCR_IDX_DESCRIPTION, ""), //$NON-NLS-1$
data.get(PKG_DESCR_IDX_AUTHOR),
data.get(PKG_DESCR_IDX_MAINTAINER),
- data.get(PKG_DESCR_IDX_URL),
+ urls,
built, task.libLocation );
}