Explorar el Código

fix #2203 pluginhelper

Shinsuke Sugaya hace 5 años
padre
commit
257619959b

+ 64 - 19
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 static org.codelibs.core.stream.StreamUtil.split;
 
 
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.File;
 import java.io.IOException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStream;
-import java.io.StringReader;
 import java.nio.file.Files;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.Paths;
@@ -30,27 +30,30 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.regex.Pattern;
 
 
 import javax.servlet.ServletContext;
 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.io.CopyUtil;
+import org.codelibs.core.lang.StringUtil;
 import org.codelibs.curl.Curl;
 import org.codelibs.curl.Curl;
 import org.codelibs.curl.CurlResponse;
 import org.codelibs.curl.CurlResponse;
+import org.codelibs.fess.crawler.Constants;
 import org.codelibs.fess.exception.PluginException;
 import org.codelibs.fess.exception.PluginException;
 import org.codelibs.fess.util.ComponentUtil;
 import org.codelibs.fess.util.ComponentUtil;
 import org.codelibs.fess.util.ResourceUtil;
 import org.codelibs.fess.util.ResourceUtil;
-import org.codelibs.nekohtml.parsers.DOMParser;
 import org.lastaflute.di.exception.IORuntimeException;
 import org.lastaflute.di.exception.IORuntimeException;
 import org.slf4j.Logger;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.w3c.dom.Document;
+import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 import org.w3c.dom.NodeList;
-import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
 
 
 // TODO: refactoring, exception handling, improving codes
 // TODO: refactoring, exception handling, improving codes
 public class PluginHelper {
 public class PluginHelper {
     private static final Logger logger = LoggerFactory.getLogger(PluginHelper.class);
     private static final Logger logger = LoggerFactory.getLogger(PluginHelper.class);
 
 
-    protected static final String VERSION = "version";
-
     public Artifact[] getArtifacts(final ArtifactType artifactType) {
     public Artifact[] getArtifacts(final ArtifactType artifactType) {
         final List<Artifact> list = new ArrayList<>();
         final List<Artifact> list = new ArrayList<>();
         for (final String url : getRepositories()) {
         for (final String url : getRepositories()) {
@@ -71,15 +74,26 @@ public class PluginHelper {
         while (matcher.find()) {
         while (matcher.find()) {
             final String name = matcher.group(1);
             final String name = matcher.group(1);
             final String pluginUrl = url + (url.endsWith("/") ? name + "/" : "/" + name + "/");
             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++) {
                 for (int i = 0; i < nodeList.getLength(); i++) {
                     final String version = nodeList.item(i).getTextContent();
                     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) {
             } catch (final Exception e) {
                 logger.warn("Failed to parse " + pluginUrl + "maven-metadata.xml.", e);
                 logger.warn("Failed to parse " + pluginUrl + "maven-metadata.xml.", e);
@@ -88,6 +102,32 @@ public class PluginHelper {
         return list;
         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) {
     protected String getRepositoryContent(final String url) {
         try (final CurlResponse response = Curl.get(url).execute()) {
         try (final CurlResponse response = Curl.get(url).execute()) {
             return response.getContentAsString();
             return response.getContentAsString();
@@ -113,7 +153,7 @@ public class PluginHelper {
         return new Artifact(artifactName, artifactVersion, null);
         return new Artifact(artifactName, artifactVersion, null);
     }
     }
 
 
-    public void installArtifact(Artifact artifact) {
+    public void installArtifact(final Artifact artifact) {
         final String fileName = artifact.getFileName();
         final String fileName = artifact.getFileName();
         try (final CurlResponse response = Curl.get(artifact.getUrl()).execute()) {
         try (final CurlResponse response = Curl.get(artifact.getUrl()).execute()) {
             try (final InputStream in = response.getContentAsStream()) {
             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 String fileName = artifact.getFileName();
         final Path jarPath = Paths.get(getPluginPath().toString(), fileName);
         final Path jarPath = Paths.get(getPluginPath().toString(), fileName);
         if (!Files.exists(jarPath)) {
         if (!Files.exists(jarPath)) {
@@ -132,7 +172,7 @@ public class PluginHelper {
         }
         }
         try {
         try {
             Files.delete(jarPath);
             Files.delete(jarPath);
-        } catch (IOException e) {
+        } catch (final IOException e) {
             throw new PluginException("Failed to delete the artifact " + fileName, 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 version;
         protected final String url;
         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.name = name;
             this.version = version;
             this.version = version;
             this.url = url;
             this.url = url;
@@ -167,14 +207,19 @@ public class PluginHelper {
         public String getUrl() {
         public String getUrl() {
             return url;
             return url;
         }
         }
+
+        @Override
+        public String toString() {
+            return "Artifact [name=" + name + ", version=" + version + "]";
+        }
     }
     }
 
 
     public enum ArtifactType {
     public enum ArtifactType {
         DATA_STORE("fess-ds"), UNKNOWN("unknown");
         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;
             this.id = id;
         }
         }
 
 
@@ -182,7 +227,7 @@ public class PluginHelper {
             return id;
             return id;
         }
         }
 
 
-        public ArtifactType getType(String name) {
+        public ArtifactType getType(final String name) {
             if (name.startsWith(DATA_STORE.getId())) {
             if (name.startsWith(DATA_STORE.getId())) {
                 return DATA_STORE;
                 return DATA_STORE;
             }
             }

+ 6 - 0
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.LanguageHelper;
 import org.codelibs.fess.helper.PathMappingHelper;
 import org.codelibs.fess.helper.PathMappingHelper;
 import org.codelibs.fess.helper.PermissionHelper;
 import org.codelibs.fess.helper.PermissionHelper;
+import org.codelibs.fess.helper.PluginHelper;
 import org.codelibs.fess.helper.PopularWordHelper;
 import org.codelibs.fess.helper.PopularWordHelper;
 import org.codelibs.fess.helper.ProcessHelper;
 import org.codelibs.fess.helper.ProcessHelper;
 import org.codelibs.fess.helper.QueryHelper;
 import org.codelibs.fess.helper.QueryHelper;
@@ -89,6 +90,8 @@ public final class ComponentUtil {
 
 
     private static Map<String, Object> componentMap = new HashMap<>();
     private static Map<String, Object> componentMap = new HashMap<>();
 
 
+    private static final String PLUGIN_HELPER = "PluginHelper";
+
     private static final String LANGUAGE_HELPER = "languageHelper";
     private static final String LANGUAGE_HELPER = "languageHelper";
 
 
     private static final String CURL_HELPER = "curlHelper";
     private static final String CURL_HELPER = "curlHelper";
@@ -439,7 +442,10 @@ public final class ComponentUtil {
 
 
     public static LanguageHelper getLanguageHelper() {
     public static LanguageHelper getLanguageHelper() {
         return getComponent(LANGUAGE_HELPER);
         return getComponent(LANGUAGE_HELPER);
+    }
 
 
+    public static PluginHelper getPluginHelper() {
+        return getComponent(PLUGIN_HELPER);
     }
     }
 
 
     public static <T> T getComponent(final Class<T> clazz) {
     public static <T> T getComponent(final Class<T> clazz) {

+ 2 - 0
src/main/resources/app.xml

@@ -32,6 +32,8 @@
 	</component>
 	</component>
 	<component name="relatedQueryHelper" class="org.codelibs.fess.helper.RelatedQueryHelper">
 	<component name="relatedQueryHelper" class="org.codelibs.fess.helper.RelatedQueryHelper">
 	</component>
 	</component>
+	<component name="pluginHelper" class="org.codelibs.fess.helper.PluginHelper">
+	</component>
 	<component name="queryStringBuilder" class="org.codelibs.fess.util.QueryStringBuilder" instance="prototype">
 	<component name="queryStringBuilder" class="org.codelibs.fess.util.QueryStringBuilder" instance="prototype">
 	</component>
 	</component>
 	<component name="queryParser" class="org.apache.lucene.queryparser.ext.ExtendableQueryParser" instance="prototype">
 	<component name="queryParser" class="org.apache.lucene.queryparser.ext.ExtendableQueryParser" instance="prototype">

+ 3 - 3
src/test/java/org/codelibs/fess/helper/PluginHelperTest.java

@@ -69,10 +69,10 @@ public class PluginHelperTest extends UnitFessTestCase {
 
 
     public void test_processRepository2() {
     public void test_processRepository2() {
         List<Artifact> list = pluginHelper.processRepository(ArtifactType.DATA_STORE, "plugin/repo2/");
         List<Artifact> 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("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() {
     public void test_getArtifactFromFileName1() {

+ 37 - 0
src/test/resources/plugin/repo2/fess-ds-atlassian/12.2.0-SNAPSHOT/maven-metadata.xml

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata modelVersion="1.1.0">
+  <groupId>org.codelibs.fess</groupId>
+  <artifactId>fess-ds-atlassian</artifactId>
+  <version>12.2.0-SNAPSHOT</version>
+  <versioning>
+    <snapshot>
+      <timestamp>20180814.210714</timestamp>
+      <buildNumber>10</buildNumber>
+    </snapshot>
+    <lastUpdated>20180814210714</lastUpdated>
+    <snapshotVersions>
+      <snapshotVersion>
+        <extension>jar</extension>
+        <value>12.2.0-20180814.210714-10</value>
+        <updated>20180814210714</updated>
+      </snapshotVersion>
+      <snapshotVersion>
+        <extension>pom</extension>
+        <value>12.2.0-20180814.210714-10</value>
+        <updated>20180814210714</updated>
+      </snapshotVersion>
+      <snapshotVersion>
+        <classifier>sources</classifier>
+        <extension>jar</extension>
+        <value>12.2.0-20180814.210714-10</value>
+        <updated>20180814210714</updated>
+      </snapshotVersion>
+      <snapshotVersion>
+        <classifier>javadoc</classifier>
+        <extension>jar</extension>
+        <value>12.2.0-20180814.210714-10</value>
+        <updated>20180814210714</updated>
+      </snapshotVersion>
+    </snapshotVersions>
+  </versioning>
+</metadata>

+ 17 - 17
src/test/resources/plugin/repo2/fess-ds-atlassian/maven-metadata.xml

@@ -1,19 +1,19 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?xml version="1.0" encoding="UTF-8"?>
-<metadata>
-    <groupId>org.codelibs.fess</groupId>
-    <artifactId>fess-ds-atlassian</artifactId>
-    <versioning>
-        <latest>13.2.0</latest>
-        <release>13.2.0</release>
-        <versions>
-            <version>12.2.0</version>
-            <version>12.5.0</version>
-            <version>12.6.0</version>
-            <version>12.7.0</version>
-            <version>13.0.0</version>
-            <version>13.1.0</version>
-            <version>13.2.0</version>
-        </versions>
-        <lastUpdated>20190704004757</lastUpdated>
-    </versioning>
+<metadata modelVersion="1.1.0">
+  <groupId>org.codelibs.fess</groupId>
+  <artifactId>fess-ds-atlassian</artifactId>
+  <versioning>
+    <latest>13.2.1-SNAPSHOT</latest>
+    <release></release>
+    <versions>
+      <version>12.2.0-SNAPSHOT</version>
+      <version>12.5.0-SNAPSHOT</version>
+      <version>12.5.1-SNAPSHOT</version>
+      <version>12.6.1-SNAPSHOT</version>
+      <version>13.0.1-SNAPSHOT</version>
+      <version>13.1.1-SNAPSHOT</version>
+      <version>13.2.1-SNAPSHOT</version>
+    </versions>
+    <lastUpdated>20190715035547</lastUpdated>
+  </versioning>
 </metadata>
 </metadata>