com.arcbees.chosen.rebind.VersionInspectorLinker Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gwtchosen Show documentation
Show all versions of gwtchosen Show documentation
GwtChosen is the GWT port of the Chosen javascript plugin that makes long, unwieldy select boxes much
more user-friendly.
/*
* Copyright 2015 ArcBees Inc.
*
* 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 com.arcbees.chosen.rebind;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.URL;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.google.gwt.core.ext.Linker;
import com.google.gwt.core.ext.LinkerContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.linker.ArtifactSet;
import com.google.gwt.core.ext.linker.ConfigurationProperty;
import com.google.gwt.core.ext.linker.LinkerOrder;
import com.google.gwt.core.ext.linker.LinkerOrder.Order;
import com.google.gwt.core.ext.linker.SelectionProperty;
import com.google.gwt.core.ext.linker.Shardable;
import static com.google.gwt.core.ext.TreeLogger.Type.DEBUG;
@Shardable
@LinkerOrder(Order.POST)
public class VersionInspectorLinker extends Linker {
private static final int CHECK_TIMEOUT_MS = 5000;
private static final String CHOSEN_EXIST_CLASS = "com.arcbees.chosen.client.Chosen";
private static final String CHOSEN_GROUP_ID = "com.arcbees";
private static final String CHOSEN_ARTIFACT = "gwtchosen";
private static final Dependency CHOSEN_DEPENDENCY =
new DependencyImpl(CHOSEN_EXIST_CLASS, CHOSEN_GROUP_ID, CHOSEN_ARTIFACT);
private static final String API_SEARCH = "http://arcbees-stats-service.appspot.com/version";
private static final String GROUP_QUERY_PARAMETER = "groupid";
private static final String ARTIFACT_QUERY_PARAMETER = "artifactid";
private static final String VERSION_QUERY_PARAMETER = "version";
private static final String PROPERTY_VERIFY_NEWER_VERSION = "verifyNewerVersion";
private static final Pattern VERSION_PATTERN = Pattern.compile("\"version\":\\s*\"([0-9](?:\\.[0-9])*)\"");
private static final Pattern LATEST_PATTERN = Pattern.compile("\"latest\":([a-z]{1,4})");
private static final Pattern RESPONSE_CONTENT_PATTERN = Pattern.compile("^[^{]*(\\{.*\\})$");
private static final String HR = "------------------------------------------------------------";
private static final String NEW_VERSION_AVAILABLE = "A new version of %s is available!";
private static final String SEE_ARTIFACT_DETAILS = "See http://search.maven.org/#artifactdetails|%s|%s|%s|jar";
private static final String YOUR_VERSION = "Your version: %s";
private static final String LATEST_VERSION = "Latest version: %s";
private Logger logger;
public VersionInspectorLinker() {
}
@Override
public String getDescription() {
return "Verify the availability of a more recent version of GWTChosen.";
}
@Override
public ArtifactSet link(TreeLogger logger, LinkerContext context, ArtifactSet artifacts, boolean onePermutation)
throws UnableToCompleteException {
if (!onePermutation && !isSuperDevMode(context) && !isTest(context) && canVerifyNewerVersion(context)) {
checkLatestVersions(logger);
}
return artifacts;
}
private boolean isSuperDevMode(LinkerContext context) {
boolean isSdm = false;
for (SelectionProperty property : context.getProperties()) {
if ("superdevmode".equals(property.getName())) {
isSdm = "on".equals(property.tryGetValue());
break;
}
}
return isSdm;
}
private boolean isTest(LinkerContext context) {
boolean isTest = false;
for (ConfigurationProperty property : context.getConfigurationProperties()) {
String name = property.getName();
List values = property.getValues();
if ("junit.moduleName".equals(name) && !values.isEmpty() && !values.get(0).isEmpty()) {
isTest = true;
break;
}
}
return isTest;
}
private boolean canVerifyNewerVersion(LinkerContext context) {
boolean verifyNewerVersion = true;
for (ConfigurationProperty property : context.getConfigurationProperties()) {
if (PROPERTY_VERIFY_NEWER_VERSION.equals(property.getName())) {
List values = property.getValues();
verifyNewerVersion = !(!values.isEmpty() && "false".equals(values.get(0)));
break;
}
}
return verifyNewerVersion;
}
private void checkLatestVersions(TreeLogger logger) {
checkLatestVersionIfPresent(logger, CHOSEN_DEPENDENCY);
}
private void checkLatestVersionIfPresent(TreeLogger baseLogger, Dependency dependency) {
if (dependency.isPresent()) {
String artifactId = dependency.getArtifactId();
logger = new Logger(baseLogger.branch(DEBUG, "Checking version information for " + artifactId));
logger.debug("You can disable this check by adding this line to your GWT module:");
logger.debug("");
checkLatestVersion(dependency);
}
}
private void checkLatestVersion(Dependency dependency) {
try {
String groupId = dependency.getGroupId();
String artifactId = dependency.getArtifactId();
String currentVersion = dependency.getVersion();
String json = fetchArtifactVersion(groupId, artifactId, currentVersion);
String latestVersion = extractVersion(json);
Boolean isLatest = extractIsLatest(json);
if (isLatest) {
logger.info("You are using the latest version of " + artifactId + "!");
} else {
warnVersion(groupId, artifactId, latestVersion, currentVersion);
}
} catch (Exception e) {
logger.getTreeLogger().log(DEBUG, "Exception caught", e);
}
}
/**
* Calls the Arcbees Stats service to retrieve data about a GWTP artifact. Note: We would use URL.openConnection,
* but because this code may be used in a GAE environment with hosted mode, this will cause fallback to the URLFetch
* Service. Using a socket bypasses this.
*
* @return The resulting plain text response
*/
private String fetchArtifactVersion(String groupId, String artifactId, String version) throws IOException {
URL maven = new URL(buildUrl(groupId, artifactId, version));
Socket socket = new Socket(maven.getHost(), 80);
socket.setSoTimeout(CHECK_TIMEOUT_MS);
String response;
try {
PrintWriter output = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream(), "UTF-8")));
output.println("GET " + maven.getFile() + " HTTP/1.1");
output.println("Host: " + maven.getHost());
output.println("Connection: close");
output.println();
output.flush();
response = readText(socket.getInputStream());
} finally {
socket.close();
}
return response;
}
private String readText(InputStream stream) throws IOException {
BufferedReader input = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
StringBuilder response = new StringBuilder();
String inputLine;
while ((inputLine = input.readLine()) != null) {
response.append(inputLine);
}
return extractResponseContent(response.toString());
}
private String extractResponseContent(String response) {
Matcher matcher = RESPONSE_CONTENT_PATTERN.matcher(response);
return matcher.find() ? matcher.group(1) : "";
}
private String extractVersion(String versionResponse) {
Matcher matcher = VERSION_PATTERN.matcher(versionResponse);
return matcher.find() ? matcher.group(1) : "";
}
private Boolean extractIsLatest(String versionResponse) {
Matcher matcher = LATEST_PATTERN.matcher(versionResponse);
return matcher.find() && Boolean.valueOf(matcher.group(1));
}
private void warnVersion(String groupId, String artifactId, String latestVersion, String currentVersion) {
logger.warn(HR);
logger.warn(NEW_VERSION_AVAILABLE, artifactId);
logger.warn(YOUR_VERSION, currentVersion);
logger.warn(LATEST_VERSION, latestVersion);
logger.warn(SEE_ARTIFACT_DETAILS, groupId, artifactId, latestVersion);
logger.warn(HR);
}
private String buildUrl(String groupId, String artifactId, String version) {
StringBuilder queryString = new StringBuilder();
appendParameter(queryString, GROUP_QUERY_PARAMETER, groupId);
appendParameter(queryString, ARTIFACT_QUERY_PARAMETER, artifactId);
appendParameter(queryString, VERSION_QUERY_PARAMETER, version);
queryString.insert(0, API_SEARCH);
return queryString.toString();
}
private void appendParameter(StringBuilder stringBuilder, String key, String value) {
if (stringBuilder.length() == 0) {
stringBuilder.append("?").append(key).append("=").append(value);
} else {
stringBuilder.append("&").append(key).append("=").append(value);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy