diff --git a/plugins/alfresco-maven-plugin/pom.xml b/plugins/alfresco-maven-plugin/pom.xml
index 43f6cdb3..f7cf6a47 100644
--- a/plugins/alfresco-maven-plugin/pom.xml
+++ b/plugins/alfresco-maven-plugin/pom.xml
@@ -79,6 +79,14 @@
maven-plugin-api3.0.4
+
+ org.apache.maven.plugin-tools
+ maven-plugin-annotations
+ 3.2
+
+ provided
+ org.apache.mavenmaven-archiver
@@ -105,6 +113,16 @@
maven-core3.0.4
+
+ org.apache.httpcomponents
+ httpclient
+ 4.3
+
+
+ commons-net
+ commons-net
+ 3.3
+ commons-iocommons-io
diff --git a/plugins/alfresco-maven-plugin/src/main/java/org/alfresco/maven/plugin/AbstractRefreshWebappMojo.java b/plugins/alfresco-maven-plugin/src/main/java/org/alfresco/maven/plugin/AbstractRefreshWebappMojo.java
new file mode 100644
index 00000000..d999191c
--- /dev/null
+++ b/plugins/alfresco-maven-plugin/src/main/java/org/alfresco/maven/plugin/AbstractRefreshWebappMojo.java
@@ -0,0 +1,287 @@
+/**
+ * Copyright (C) 2015 Alfresco Software Limited.
+ *
+ * This file is part of the Alfresco SDK.
+ *
+ * Licensed 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.alfresco.maven.plugin;
+
+import org.apache.commons.net.telnet.TelnetClient;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpStatus;
+import org.apache.http.NameValuePair;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.AuthCache;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.impl.auth.BasicScheme;
+import org.apache.http.impl.client.BasicAuthCache;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.annotations.Parameter;
+
+import java.io.Closeable;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Abstract Maven Mojo with generic functionality common to
+ * both the Refresh Repo and Refresh Share Mojos.
+ *
+ * @author martin.bergljung@alfresco.com
+ * @since 2.1.0
+ */
+public abstract class AbstractRefreshWebappMojo extends AbstractMojo {
+ public static final String DEFAULT_USERNAME = "admin";
+ public static final String DEFAULT_PASSWORD = "admin";
+ public static final String DEFAULT_HOST = "localhost";
+ public static final String DEFAULT_PORT = "8080";
+
+ /**
+ * The hostname for where the Alfresco Tomcat server is running.
+ */
+ @Parameter(property = "refreshHost", defaultValue = DEFAULT_USERNAME, alias = "refreshHost")
+ private String _host = DEFAULT_HOST;
+
+ /**
+ * The port number for where the Alfresco Tomcat server is running.
+ */
+ @Parameter(property = "refreshPort", defaultValue = DEFAULT_USERNAME, alias = "refreshPort")
+ private String _port = DEFAULT_PORT;
+
+ /**
+ * The username for authenticating against Alfresco Repo.
+ */
+ @Parameter(property = "refreshUsername", defaultValue = DEFAULT_USERNAME, alias = "refreshUsername")
+ private String _username = DEFAULT_USERNAME;
+
+ /**
+ * The password for authenticating against Alfresco Repo.
+ */
+ @Parameter(property = "refreshPassword", defaultValue = DEFAULT_PASSWORD, alias = "refreshPassword")
+ private String _password = DEFAULT_PASSWORD;
+
+ /**
+ * The Refresh URL to call, can be either for Share or Repo
+ */
+ private String refreshUrl;
+
+ /**
+ * The Clear Dependency Caches URL to call, currently only applicable to Share.
+ */
+ private String clearDependencyCachesUrl;
+
+ /**
+ * The name of the web application we are refreshing, just for logging purpose
+ */
+ private String refreshWebappName;
+
+ /**
+ * Mojo interface implementation
+ */
+
+ @Override
+ public void execute() throws MojoExecutionException {
+ // Do a ping to see if the server is up, if not, log and just exit
+ if (!ping()) {
+ getLog().warn("Connection failed to " + _host + ":" + _port + ", " + getAbortedMsg());
+ return;
+ }
+
+ executeRefresh();
+ }
+
+ /**
+ * To be implemented by webapp "refresh" Mojos
+ */
+ protected abstract void executeRefresh();
+
+ /**
+ * The following methods are called by specific refresh mojo implementations
+ */
+
+ protected void setRefreshUrl(String refreshUrl) {
+ this.refreshUrl = refreshUrl;
+ }
+
+ protected void setClearDependencyCachesUrl(String clearDependencyCachesUrl) {
+ this.clearDependencyCachesUrl = clearDependencyCachesUrl;
+ }
+
+ protected void setWebappName(String refreshWebappName) {
+ this.refreshWebappName = refreshWebappName;
+ }
+
+ /**
+ * Perform a Refresh of Web Scripts container in webapp.
+ * Called by specific refresh mojo implementation.
+ */
+ protected void refreshWebScripts() {
+ // Create the Refresh URL for the Alfresco Tomcat server
+ URL alfrescoTomcatUrl = buildFinalUrl(refreshUrl);
+ if (alfrescoTomcatUrl == null) {
+ getLog().error("Could not build refresh URL for " + refreshWebappName + ", " + getAbortedMsg());
+ }
+
+ // Set up the data we need to POST to the server for the refresh to work
+ List postData = new ArrayList();
+ postData.add(new BasicNameValuePair("reset", "on"));
+ postData.add(new BasicNameValuePair("submit", "Refresh Web Scripts"));
+
+ // Do the refresh
+ makePostCall(alfrescoTomcatUrl, postData, "Refresh Web Scripts");
+ }
+
+ /**
+ * Perform a Clear Dependency Caches call on Share webapp.
+ * Called by specific refresh mojo implementation, currently only applicable to Share webapp.
+ */
+ protected void clearDependencyCaches() {
+ // Create the Clear Cache URL for the Alfresco Tomcat server
+ URL alfrescoTomcatUrl = buildFinalUrl(clearDependencyCachesUrl);
+ if (alfrescoTomcatUrl == null) {
+ getLog().error("Could not build clear dependency caches URL for " +
+ refreshWebappName + ", " + getAbortedMsg());
+ }
+
+ // Do the refresh
+ makePostCall(alfrescoTomcatUrl, null, "Clear Dependency Caches");
+ }
+
+ /**
+ * Helper method to make a POST request to the Alfresco Webapp
+ *
+ * @param alfrescoTomcatUrl the URL for the webapp we want to post to
+ * @param postData the POST data that should be sent
+ * @param operation information about the operation we are performing
+ */
+ private void makePostCall(URL alfrescoTomcatUrl, List postData, String operation) {
+ CloseableHttpClient client = null;
+ CloseableHttpResponse response = null;
+ try {
+ // Set up a HTTP POST request to the Alfresco Webapp we are targeting
+ HttpHost targetHost = new HttpHost(
+ alfrescoTomcatUrl.getHost(), alfrescoTomcatUrl.getPort(), alfrescoTomcatUrl.getProtocol());
+
+ // Set up authentication parameters
+ CredentialsProvider credsProvider = new BasicCredentialsProvider();
+ credsProvider.setCredentials(new AuthScope(targetHost.getHostName(), targetHost.getPort()),
+ new UsernamePasswordCredentials(_username, _password));
+
+ // Create the HTTP Client we will use to make the call
+ client = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
+
+ // Create AuthCache instance
+ AuthCache authCache = new BasicAuthCache();
+
+ // Generate BASIC scheme object and add it to the local auth cache
+ BasicScheme basicAuth = new BasicScheme();
+ authCache.put(targetHost, basicAuth);
+
+ // Add AuthCache to the execution context
+ HttpClientContext localContext = HttpClientContext.create();
+ localContext.setAuthCache(authCache);
+
+ // Make the call to Refresh the Alfresco Webapp
+ HttpPost httpPost = new HttpPost(alfrescoTomcatUrl.toURI());
+ response = client.execute(httpPost);
+ if (postData != null) {
+ UrlEncodedFormEntity entity = new UrlEncodedFormEntity(postData, "UTF-8");
+ httpPost.setEntity(entity);
+ }
+ httpPost.setHeader("Accept-Charset", "iso-8859-1,utf-8");
+ httpPost.setHeader("Accept-Language", "en-us");
+ response = client.execute(httpPost);
+
+ // If no response, no method has been passed
+ if (response == null) {
+ getLog().error("POST request failed to " + alfrescoTomcatUrl.toString() + ", " + getAbortedMsg());
+ return;
+ }
+
+ // Check if we got a successful response or not
+ int statusCode = response.getStatusLine().getStatusCode();
+ if (statusCode == HttpStatus.SC_OK) {
+ getLog().info("Successfull " + operation + " for " + refreshWebappName);
+ } else {
+ String reasonPhrase = response.getStatusLine().getReasonPhrase();
+ getLog().warn("Failed to " + operation + " for " + refreshWebappName + ". Response status: " +
+ statusCode + ", message: " + reasonPhrase);
+ }
+ } catch (Exception ex) {
+ getLog().error("POST request failed to " + _host + ":" + _port + refreshUrl + ", " + getAbortedMsg());
+ getLog().error("Exception Msg: " + ex.getMessage());
+ } finally {
+ closeQuietly(response);
+ closeQuietly(client);
+ }
+ }
+
+ private URL buildFinalUrl(String specificRefreshUrlPath) {
+ try {
+ return new URL("http://" + _host + ":" + _port + specificRefreshUrlPath);
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * Utility method to ping/call the Alfresco Tomcat server and see if it is up (running)
+ *
+ * @return true if the Alfresco Tomcat server was reachable and up
+ */
+ private boolean ping() {
+ try {
+ URL alfrescoTomcatUrl = buildFinalUrl("");
+ TelnetClient telnetClient = new TelnetClient();
+ telnetClient.setDefaultTimeout(500);
+ telnetClient.connect(alfrescoTomcatUrl.getHost(), alfrescoTomcatUrl.getPort());
+ return true;
+ } catch (Exception ex) {
+ return false;
+ }
+ }
+
+ /**
+ * Close down communication objects without any messages
+ *
+ * @param closeable
+ */
+ private void closeQuietly(Closeable closeable) {
+ try {
+ closeable.close();
+ } catch (Exception ex) {
+ // swallow any exceptions
+ }
+ }
+
+ /**
+ * Helper to get consistent aborted message
+ * @return
+ */
+ private String getAbortedMsg() {
+ return refreshWebappName + " webapp refresh aborted";
+ }
+}
diff --git a/plugins/alfresco-maven-plugin/src/main/java/org/alfresco/maven/plugin/RefreshRepoWebappMojo.java b/plugins/alfresco-maven-plugin/src/main/java/org/alfresco/maven/plugin/RefreshRepoWebappMojo.java
new file mode 100644
index 00000000..3ed6baef
--- /dev/null
+++ b/plugins/alfresco-maven-plugin/src/main/java/org/alfresco/maven/plugin/RefreshRepoWebappMojo.java
@@ -0,0 +1,55 @@
+/**
+ * Copyright (C) 2015 Alfresco Software Limited.
+ *
+ * This file is part of the Alfresco SDK.
+ *
+ * Licensed 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.alfresco.maven.plugin;
+
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+
+/**
+ * Refresh Alfresco Repository (alfresco.war) Mojo.
+ * Will refresh the Web Script container so new and changed
+ * Web Scripts are detected.
+ *
+ * It is important to execute the refresh calls in the compile phase,
+ * otherwise the files will be copied after this and the refresh calls
+ * will not be recognized.
+ *
+ * @author martin.bergljung@alfresco.com
+ * @since 2.1.0
+ */
+@Mojo(name = "refresh-repo", defaultPhase = LifecyclePhase.COMPILE)
+public class RefreshRepoWebappMojo extends AbstractRefreshWebappMojo {
+ public static final String DEFAULT_REPO_REFRESH_URL = "/alfresco/service/index";
+
+ /**
+ * The URL to send the POST to when you want to refresh Alfresco Repo Web Scripts container.
+ */
+ @Parameter(property = "refreshRepoUrl", required = true, alias = "refreshRepoUrl")
+ private String _refreshRepoUrl = DEFAULT_REPO_REFRESH_URL;
+
+ public RefreshRepoWebappMojo() {
+ setRefreshUrl(_refreshRepoUrl);
+ setWebappName("Alfresco Repository");
+ }
+
+ @Override
+ protected void executeRefresh() {
+ refreshWebScripts();
+ }
+}
diff --git a/plugins/alfresco-maven-plugin/src/main/java/org/alfresco/maven/plugin/RefreshShareWebappMojo.java b/plugins/alfresco-maven-plugin/src/main/java/org/alfresco/maven/plugin/RefreshShareWebappMojo.java
new file mode 100644
index 00000000..91a4c6f7
--- /dev/null
+++ b/plugins/alfresco-maven-plugin/src/main/java/org/alfresco/maven/plugin/RefreshShareWebappMojo.java
@@ -0,0 +1,67 @@
+/**
+ * Copyright (C) 2015 Alfresco Software Limited.
+ *
+ * This file is part of the Alfresco SDK.
+ *
+ * Licensed 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.alfresco.maven.plugin;
+
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+
+/**
+ * Refresh Alfresco Share (share.war) Mojo.
+ * Will refresh the Web Script container so new and changed
+ * Spring Surf Web Scripts are detected.
+ * Will also clear the dependency caches for web resources (CSS, JS, etc).
+ *
+ * It is important to execute the refresh calls in the compile phase,
+ * otherwise the files will be copied after this and the refresh calls
+ * will not be recognized.
+ *
+ * @author martin.bergljung@alfresco.com
+ * @since 2.1.0
+ */
+@Mojo(name = "refresh-share", defaultPhase = LifecyclePhase.COMPILE)
+public class RefreshShareWebappMojo extends AbstractRefreshWebappMojo {
+ public static final String DEFAULT_SHARE_REFRESH_URL = "/share/page/index";
+ public static final String DEFAULT_SHARE_CLEAR_DEPENDENCY_CACHES_URL = "/share/page/caches/dependency/clear";
+
+ /**
+ * The URL to send the POST to when you want to refresh Alfresco Share Spring Surf Web Scripts container.
+ */
+ @Parameter(property = "refreshShareUrl", required = true, alias = "refreshShareUrl")
+ private String _refreshShareUrl = DEFAULT_SHARE_REFRESH_URL;
+
+ /**
+ * The URL to send the POST to when you want to clear dependency caches for the Alfresco Share webapp.
+ */
+ @Parameter(property = "clearCacheShareUrl", required = true, alias = "clearCacheShareUrl")
+ private String _clearCacheShareUrl = DEFAULT_SHARE_CLEAR_DEPENDENCY_CACHES_URL;
+
+ public RefreshShareWebappMojo() {
+ setRefreshUrl(_refreshShareUrl);
+ setClearDependencyCachesUrl(_clearCacheShareUrl);
+ setWebappName("Alfresco Share");
+ }
+
+ /**
+ * Call the Share Webapp and refresh web scripts and clear caches.
+ */
+ protected void executeRefresh() {
+ refreshWebScripts();
+ clearDependencyCaches();
+ }
+}
diff --git a/poms/alfresco-sdk-parent/pom.xml b/poms/alfresco-sdk-parent/pom.xml
index 23e98293..6974b8d5 100644
--- a/poms/alfresco-sdk-parent/pom.xml
+++ b/poms/alfresco-sdk-parent/pom.xml
@@ -228,6 +228,13 @@
truetrue
+ localhost
+ 8080
+ /alfresco/service/index
+ /share/page/index
+ /share/page/caches/dependency/clear
+ admin
+ admin
@@ -411,25 +418,6 @@
-
- org.codehaus.groovy.maven
- gmaven-plugin
- 1.0
-
-
-
- compile
-
- execute
-
-
-
-
@@ -518,124 +506,6 @@
-
-
- refresh-share
-
-
- org.codehaus.groovy.modules.http-builder
- http-builder
- 0.7.1
-
-
-
-
-
- org.codehaus.groovy.maven
- gmaven-plugin
-
-
-
-
- ${maven.tomcat.port}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- refresh-repo
-
-
- org.codehaus.groovy.modules.http-builder
- http-builder
- 0.7.1
-
-
-
-
-
- org.codehaus.groovy.maven
- gmaven-plugin
- 1.0
-
-
-
-
- ${maven.tomcat.port}
-
-
-
-
-
-
-
-
-
-
-
-
-