diff --git a/src/main/java/org/codelibs/fess/helper/PluginHelper.java b/src/main/java/org/codelibs/fess/helper/PluginHelper.java index c9935eda6..d40201b3b 100644 --- a/src/main/java/org/codelibs/fess/helper/PluginHelper.java +++ b/src/main/java/org/codelibs/fess/helper/PluginHelper.java @@ -17,10 +17,10 @@ package org.codelibs.fess.helper; import static org.codelibs.core.stream.StreamUtil.split; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.io.StringReader; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -30,27 +30,30 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.ServletContext; +import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; import org.codelibs.core.io.CopyUtil; +import org.codelibs.core.lang.StringUtil; import org.codelibs.curl.Curl; import org.codelibs.curl.CurlResponse; +import org.codelibs.fess.crawler.Constants; import org.codelibs.fess.exception.PluginException; import org.codelibs.fess.util.ComponentUtil; import org.codelibs.fess.util.ResourceUtil; -import org.codelibs.nekohtml.parsers.DOMParser; import org.lastaflute.di.exception.IORuntimeException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; +import org.w3c.dom.Node; import org.w3c.dom.NodeList; -import org.xml.sax.InputSource; +import org.xml.sax.SAXException; // TODO: refactoring, exception handling, improving codes public class PluginHelper { private static final Logger logger = LoggerFactory.getLogger(PluginHelper.class); - protected static final String VERSION = "version"; - public Artifact[] getArtifacts(final ArtifactType artifactType) { final List list = new ArrayList<>(); for (final String url : getRepositories()) { @@ -71,15 +74,26 @@ public class PluginHelper { while (matcher.find()) { final String name = matcher.group(1); final String pluginUrl = url + (url.endsWith("/") ? name + "/" : "/" + name + "/"); - final String mavenMetadata = getRepositoryContent(pluginUrl + "maven-metadata.xml"); - try (final StringReader reader = new StringReader(mavenMetadata)) { - final DOMParser parser = new DOMParser(); - parser.parse(new InputSource(reader)); - final Document document = parser.getDocument(); - final NodeList nodeList = document.getElementsByTagName(VERSION); + final String pluginMetaContent = getRepositoryContent(pluginUrl + "maven-metadata.xml"); + try (final InputStream is = new ByteArrayInputStream(pluginMetaContent.getBytes(Constants.UTF_8_CHARSET))) { + final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + final DocumentBuilder builder = factory.newDocumentBuilder(); + final Document document = builder.parse(is); + final NodeList nodeList = document.getElementsByTagName("version"); for (int i = 0; i < nodeList.getLength(); i++) { final String version = nodeList.item(i).getTextContent(); - list.add(new Artifact(name, version, pluginUrl + version + "/" + name + "-" + version + ".jar")); + if (version.endsWith("SNAPSHOT")) { + final String snapshotVersion = getSnapshotActualVersion(builder, pluginUrl, version); + if (StringUtil.isNotBlank(snapshotVersion)) { + String actualVersion = version.replace("SNAPSHOT", snapshotVersion); + list.add(new Artifact(name, actualVersion, pluginUrl + version + "/" + name + "-" + actualVersion + ".jar")); + } else if (logger.isDebugEnabled()) { + logger.debug("Snapshot name is not found: " + name + "/" + version); + } + } else { + list.add(new Artifact(name, version, pluginUrl + version + "/" + name + "-" + version + ".jar")); + } } } catch (final Exception e) { logger.warn("Failed to parse " + pluginUrl + "maven-metadata.xml.", e); @@ -88,6 +102,32 @@ public class PluginHelper { return list; } + protected String getSnapshotActualVersion(final DocumentBuilder builder, final String pluginUrl, final String version) + throws SAXException, IOException { + String timestamp = null; + String buildNumber = null; + final String versionMetaContent = getRepositoryContent(pluginUrl + version + "/maven-metadata.xml"); + try (final InputStream is = new ByteArrayInputStream(versionMetaContent.getBytes(Constants.UTF_8_CHARSET))) { + final Document doc = builder.parse(is); + final NodeList snapshotNodeList = doc.getElementsByTagName("snapshot"); + if (snapshotNodeList.getLength() > 0) { + NodeList nodeList = snapshotNodeList.item(0).getChildNodes(); + for (int i = 0; i < nodeList.getLength(); i++) { + final Node node = nodeList.item(i); + if ("timestamp".equalsIgnoreCase(node.getNodeName())) { + timestamp = node.getTextContent(); + } else if ("buildNumber".equalsIgnoreCase(node.getNodeName())) { + buildNumber = node.getTextContent(); + } + } + } + } + if (StringUtil.isNotBlank(timestamp) && StringUtil.isNotBlank(buildNumber)) { + return timestamp + "-" + buildNumber; + } + return null; + } + protected String getRepositoryContent(final String url) { try (final CurlResponse response = Curl.get(url).execute()) { return response.getContentAsString(); @@ -113,7 +153,7 @@ public class PluginHelper { return new Artifact(artifactName, artifactVersion, null); } - public void installArtifact(Artifact artifact) { + public void installArtifact(final Artifact artifact) { final String fileName = artifact.getFileName(); try (final CurlResponse response = Curl.get(artifact.getUrl()).execute()) { try (final InputStream in = response.getContentAsStream()) { @@ -124,7 +164,7 @@ public class PluginHelper { } } - public void deleteInstalledArtifact(Artifact artifact) { + public void deleteInstalledArtifact(final Artifact artifact) { final String fileName = artifact.getFileName(); final Path jarPath = Paths.get(getPluginPath().toString(), fileName); if (!Files.exists(jarPath)) { @@ -132,7 +172,7 @@ public class PluginHelper { } try { Files.delete(jarPath); - } catch (IOException e) { + } catch (final IOException e) { throw new PluginException("Failed to delete the artifact " + fileName, e); } } @@ -146,7 +186,7 @@ public class PluginHelper { protected final String version; protected final String url; - public Artifact(String name, String version, String url) { + public Artifact(final String name, final String version, final String url) { this.name = name; this.version = version; this.url = url; @@ -167,14 +207,19 @@ public class PluginHelper { public String getUrl() { return url; } + + @Override + public String toString() { + return "Artifact [name=" + name + ", version=" + version + "]"; + } } public enum ArtifactType { DATA_STORE("fess-ds"), UNKNOWN("unknown"); - private String id; + private final String id; - private ArtifactType(String id) { + private ArtifactType(final String id) { this.id = id; } @@ -182,7 +227,7 @@ public class PluginHelper { return id; } - public ArtifactType getType(String name) { + public ArtifactType getType(final String name) { if (name.startsWith(DATA_STORE.getId())) { return DATA_STORE; } diff --git a/src/main/java/org/codelibs/fess/util/ComponentUtil.java b/src/main/java/org/codelibs/fess/util/ComponentUtil.java index 664ff7aad..902c29e99 100644 --- a/src/main/java/org/codelibs/fess/util/ComponentUtil.java +++ b/src/main/java/org/codelibs/fess/util/ComponentUtil.java @@ -50,6 +50,7 @@ import org.codelibs.fess.helper.LabelTypeHelper; import org.codelibs.fess.helper.LanguageHelper; import org.codelibs.fess.helper.PathMappingHelper; import org.codelibs.fess.helper.PermissionHelper; +import org.codelibs.fess.helper.PluginHelper; import org.codelibs.fess.helper.PopularWordHelper; import org.codelibs.fess.helper.ProcessHelper; import org.codelibs.fess.helper.QueryHelper; @@ -89,6 +90,8 @@ public final class ComponentUtil { private static Map componentMap = new HashMap<>(); + private static final String PLUGIN_HELPER = "PluginHelper"; + private static final String LANGUAGE_HELPER = "languageHelper"; private static final String CURL_HELPER = "curlHelper"; @@ -439,7 +442,10 @@ public final class ComponentUtil { public static LanguageHelper getLanguageHelper() { return getComponent(LANGUAGE_HELPER); + } + public static PluginHelper getPluginHelper() { + return getComponent(PLUGIN_HELPER); } public static T getComponent(final Class clazz) { diff --git a/src/main/resources/app.xml b/src/main/resources/app.xml index f55239dfa..365e5a832 100644 --- a/src/main/resources/app.xml +++ b/src/main/resources/app.xml @@ -32,6 +32,8 @@ + + diff --git a/src/test/java/org/codelibs/fess/helper/PluginHelperTest.java b/src/test/java/org/codelibs/fess/helper/PluginHelperTest.java index 987c6c845..15eeed478 100644 --- a/src/test/java/org/codelibs/fess/helper/PluginHelperTest.java +++ b/src/test/java/org/codelibs/fess/helper/PluginHelperTest.java @@ -69,10 +69,10 @@ public class PluginHelperTest extends UnitFessTestCase { public void test_processRepository2() { List list = pluginHelper.processRepository(ArtifactType.DATA_STORE, "plugin/repo2/"); - assertEquals(7, list.size()); + assertEquals(1, list.size()); assertEquals("fess-ds-atlassian", list.get(0).getName()); - assertEquals("12.2.0", list.get(0).getVersion()); - assertEquals("plugin/repo2/fess-ds-atlassian/12.2.0/fess-ds-atlassian-12.2.0.jar", list.get(0).getUrl()); + assertEquals("12.2.0-20180814.210714-10", list.get(0).getVersion()); + assertEquals("plugin/repo2/fess-ds-atlassian/12.2.0-SNAPSHOT/fess-ds-atlassian-12.2.0-20180814.210714-10.jar", list.get(0).getUrl()); } public void test_getArtifactFromFileName1() { diff --git a/src/test/resources/plugin/repo2/fess-ds-atlassian/12.2.0-SNAPSHOT/maven-metadata.xml b/src/test/resources/plugin/repo2/fess-ds-atlassian/12.2.0-SNAPSHOT/maven-metadata.xml new file mode 100644 index 000000000..b9f035407 --- /dev/null +++ b/src/test/resources/plugin/repo2/fess-ds-atlassian/12.2.0-SNAPSHOT/maven-metadata.xml @@ -0,0 +1,37 @@ + + + org.codelibs.fess + fess-ds-atlassian + 12.2.0-SNAPSHOT + + + 20180814.210714 + 10 + + 20180814210714 + + + jar + 12.2.0-20180814.210714-10 + 20180814210714 + + + pom + 12.2.0-20180814.210714-10 + 20180814210714 + + + sources + jar + 12.2.0-20180814.210714-10 + 20180814210714 + + + javadoc + jar + 12.2.0-20180814.210714-10 + 20180814210714 + + + + diff --git a/src/test/resources/plugin/repo2/fess-ds-atlassian/maven-metadata.xml b/src/test/resources/plugin/repo2/fess-ds-atlassian/maven-metadata.xml index 4fe72eedf..a8986c47c 100644 --- a/src/test/resources/plugin/repo2/fess-ds-atlassian/maven-metadata.xml +++ b/src/test/resources/plugin/repo2/fess-ds-atlassian/maven-metadata.xml @@ -1,19 +1,19 @@ - - org.codelibs.fess - fess-ds-atlassian - - 13.2.0 - 13.2.0 - - 12.2.0 - 12.5.0 - 12.6.0 - 12.7.0 - 13.0.0 - 13.1.0 - 13.2.0 - - 20190704004757 - + + org.codelibs.fess + fess-ds-atlassian + + 13.2.1-SNAPSHOT + + + 12.2.0-SNAPSHOT + 12.5.0-SNAPSHOT + 12.5.1-SNAPSHOT + 12.6.1-SNAPSHOT + 13.0.1-SNAPSHOT + 13.1.1-SNAPSHOT + 13.2.1-SNAPSHOT + + 20190715035547 +