Java tutorial
/* * Copyright 2016 Red Hat, Inc. * * Red Hat licenses this file to you 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 io.fabric8.maven.enricher.fabric8; import java.io.File; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.net.URLConnection; import java.util.Collections; import java.util.Map; import com.google.common.io.Files; import io.fabric8.maven.core.util.Configs; import io.fabric8.maven.core.util.FileUtil; import io.fabric8.maven.core.util.MavenUtil; import io.fabric8.maven.core.util.SpringBootConfigurationHelper; import io.fabric8.maven.core.util.kubernetes.Fabric8Annotations; import io.fabric8.maven.enricher.api.BaseEnricher; import io.fabric8.maven.enricher.api.EnricherContext; import io.fabric8.maven.enricher.api.Kind; import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.apache.maven.model.Scm; import org.apache.maven.project.MavenProject; import static io.fabric8.maven.core.util.MavenUtil.hasClass; import static io.fabric8.maven.core.util.MavenUtil.hasPlugin; import static io.fabric8.maven.core.util.MavenUtil.hasPluginOfAnyGroupId; /** * Enricher for adding icons to descriptors * * @author roland * @since 01/05/16 */ public class IconEnricher extends BaseEnricher { private static String[] ICON_EXTENSIONS = new String[] { ".svg", ".png", ".gif", ".jpg", ".jpeg" }; private File templateTempDir; private File appConfigDir; private String iconBranch; // Available configuration keys private enum Config implements Configs.Key { templateTempDir, sourceDir, ref, maximumDataUrlSizeK { { d = "2"; } }, urlPrefix, branch { { d = "master"; } }, url; public String def() { return d; } protected String d; } public IconEnricher(EnricherContext buildContext) { super(buildContext, "f8-icon"); String baseDir = getProject().getBasedir().getAbsolutePath(); templateTempDir = new File(getConfig(Config.templateTempDir, baseDir + "/target/fabric8/template-workdir")); appConfigDir = new File(getConfig(Config.sourceDir, baseDir + "/src/main/fabric8")); } @Override public Map<String, String> getAnnotations(Kind kind) { if (kind.isController() || kind == Kind.SERVICE) { String iconUrl = getIconUrl(extractIconRef()); if (iconUrl != null) { log.info("Adding icon for %s", kind.toString().toLowerCase()); log.verbose("Icon URL: %s", iconUrl); return Collections.singletonMap(Fabric8Annotations.ICON_URL.value(), iconUrl); } else { log.debug("No icon file found for resources of type " + kind); } } return null; } // ==================================================================================================== private String extractIconRef() { String iconRef = getConfig(Config.ref); if (StringUtils.isBlank(iconRef)) { iconRef = getDefaultIconRef(); } return iconRef; } protected String getIconUrl(String iconRef) { String answer = getConfig(Config.url); if (StringUtils.isBlank(answer)) { try { if (templateTempDir != null) { templateTempDir.mkdirs(); File iconFile = copyIconToFolder(iconRef, templateTempDir); if (iconFile == null) { copyAppConfigFiles(templateTempDir, appConfigDir); // lets find the icon file... for (String ext : ICON_EXTENSIONS) { File file = new File(templateTempDir, "icon" + ext); if (file.exists() && file.isFile()) { iconFile = file; break; } } } if (iconFile != null) { answer = convertIconFileToURL(iconFile, iconRef); } } } catch (Exception e) { log.warn("Failed to load icon file: %s", e); } } if (StringUtils.isBlank(answer)) { // maybe its a common icon that is embedded in fabric8-console if (StringUtils.isNotBlank(iconRef)) { String embeddedIcon = embeddedIconsInConsole(iconRef, "img/icons/"); if (embeddedIcon != null) { return embeddedIcon; } else { log.warn("Could not resolve iconRef: %s", iconRef); } } } return answer; } /** * Lets use the project and its classpath to try figure out what default icon to use * * @return the icon ref if we can detect one or return null */ private String getDefaultIconRef() { MavenProject project = getProject(); EnricherContext context = getContext(); if (hasClass(project, "io.fabric8.funktion.runtime.Main") || MavenUtil.hasDependencyOnAnyArtifactOfGroup(project, "io.fabric8.funktion")) { return "funktion"; } if (hasClass(project, "org.apache.camel.CamelContext")) { return "camel"; } if (hasPluginOfAnyGroupId(project, SpringBootConfigurationHelper.SPRING_BOOT_MAVEN_PLUGIN_ARTIFACT_ID) || hasClass(project, "org.springframework.boot.SpringApplication")) { return "spring-boot"; } if (hasClass(project, "org.springframework.core.Constants")) { return "spring"; } if (hasClass(project, "org.vertx.java.core.Handler", "io.vertx.core.Handler")) { return "vertx"; } if (hasPlugin(project, "org.wildfly.swarm:wildfly-swarm-plugin") || MavenUtil.hasDependencyOnAnyArtifactOfGroup(project, "org.wildfly.swarm")) { return "wildfly-swarm"; } if (hasPlugin(project, "io.thorntail:thorntail-maven-plugin") || MavenUtil.hasDependencyOnAnyArtifactOfGroup(project, "io.thorntail")) { // use the WildFly Swarm icon until there's a dedicated Thorntail icon // Thorntail is a new name of WildFly Swarm return "wildfly-swarm"; } return null; } private File copyIconToFolder(String iconRef, File appBuildDir) throws IOException { if (StringUtils.isNotBlank(iconRef)) { File[] icons = appBuildDir.listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { if (name == null) { return false; } String lower = name.toLowerCase(); if (lower.startsWith("icon.")) { for (String ext : ICON_EXTENSIONS) { if (lower.endsWith(ext)) { return true; } } } return false; } }); if (icons == null || icons.length == 0) { // lets copy the iconRef InputStream in = loadPluginResource(iconRef); if (in == null) { // maybe it dont have extension so try to find it for (String ext : ICON_EXTENSIONS) { String name = iconRef + ext; in = loadPluginResource(name); if (in != null) { iconRef = name; break; } } } if (in != null) { String fileName = "icon." + Files.getFileExtension(iconRef); File outFile = new File(appBuildDir, fileName); FileUtils.copyInputStreamToFile(in, outFile); log.info("Generated icon file " + outFile + " from icon reference: " + iconRef); return outFile; } } } return null; } private InputStream loadPluginResource(String iconRef) { InputStream answer = Thread.currentThread().getContextClassLoader().getResourceAsStream(iconRef); if (answer == null) { answer = MavenUtil.getTestClassLoader(getProject()).getResourceAsStream(iconRef); } if (answer == null) { answer = this.getClass().getResourceAsStream(iconRef); } return answer; } /** * Copies any local configuration files into the app directory */ private void copyAppConfigFiles(File appBuildDir, File appConfigDir) throws IOException { File[] files = appConfigDir.listFiles(); if (files != null) { appBuildDir.mkdirs(); for (File file : files) { File outFile = new File(appBuildDir, file.getName()); if (file.isDirectory()) { copyAppConfigFiles(outFile, file); } else { Files.copy(file, outFile); } } } } private String convertIconFileToURL(File iconFile, String iconRef) throws IOException { long length = iconFile.length(); int sizeK = Math.round(length / 1024); byte[] bytes = FileUtils.readFileToByteArray(iconFile); byte[] encoded = Base64.encodeBase64(bytes); int base64SizeK = Math.round(encoded.length / 1024); if (base64SizeK < Configs.asInt(getConfig(Config.maximumDataUrlSizeK))) { String mimeType = URLConnection.guessContentTypeFromName(iconFile.getName()); return "data:" + mimeType + ";charset=UTF-8;base64," + new String(encoded); } else { File iconSourceFile = new File(appConfigDir, iconFile.getName()); if (iconSourceFile.exists()) { File rootProjectFolder = getRootProjectFolder(); if (rootProjectFolder != null) { String relativePath = FileUtil.getRelativePath(rootProjectFolder, iconSourceFile).toString(); String relativeParentPath = FileUtil .getRelativePath(rootProjectFolder, getProject().getBasedir()).toString(); String urlPrefix = getConfig(Config.urlPrefix); if (StringUtils.isBlank(urlPrefix)) { Scm scm = getProject().getScm(); if (scm != null) { String url = scm.getUrl(); if (url != null) { String[] prefixes = { "http://github.com/", "https://github.com/" }; for (String prefix : prefixes) { if (url.startsWith(prefix)) { url = "https://cdn.rawgit.com/" + url.substring(prefix.length()); break; } } if (url.endsWith(relativeParentPath)) { url = url.substring(0, url.length() - relativeParentPath.length()); } urlPrefix = url; } } } if (StringUtils.isBlank(urlPrefix)) { log.warn( "No iconUrlPrefix defined or could be found via SCM in the pom.xml so cannot add an icon URL!"); } else { return String.format("%s/%s/%s", urlPrefix, getConfig(Config.branch), relativePath); } } } else { String embeddedIcon = embeddedIconsInConsole(iconRef, "img/icons/"); if (embeddedIcon != null) { return embeddedIcon; } else { log.warn("Cannot find url for icon to use %s", iconRef); } } } return null; } /** * Returns the root project folder */ protected File getRootProjectFolder() { File answer = null; MavenProject project = getProject(); while (project != null) { File basedir = project.getBasedir(); if (basedir != null) { answer = basedir; } project = project.getParent(); } return answer; } /** * To use embedded icons provided by the fabric8-console * * @param iconRef name of icon file * @param prefix prefix location for the icons in the fabric8-console * @return the embedded icon ref, or <tt>null</tt> if no embedded icon found to be used */ protected String embeddedIconsInConsole(String iconRef, String prefix) { if (iconRef == null) { return null; } if (iconRef.startsWith("icons/")) { iconRef = iconRef.substring(6); } // special for fabric8 as its in a different dir if (iconRef.contains("fabric8")) { return "img/fabric8_icon.svg"; } if (iconRef.contains("activemq")) { return prefix + "activemq.svg"; } else if (iconRef.contains("apiman")) { return prefix + "apiman.png"; } else if (iconRef.contains("api-registry")) { return prefix + "api-registry.svg"; } else if (iconRef.contains("brackets")) { return prefix + "brackets.svg"; } else if (iconRef.contains("camel")) { return prefix + "camel.svg"; } else if (iconRef.contains("chaos-monkey")) { return prefix + "chaos-monkey.png"; } else if (iconRef.contains("docker-registry")) { return prefix + "docker-registry.png"; } else if (iconRef.contains("elasticsearch")) { return prefix + "elasticsearch.png"; } else if (iconRef.contains("fluentd")) { return prefix + "fluentd.png"; } else if (iconRef.contains("forge")) { return prefix + "forge.svg"; } else if (iconRef.contains("funktion")) { return prefix + "funktion.png"; } else if (iconRef.contains("gerrit")) { return prefix + "gerrit.png"; } else if (iconRef.contains("gitlab")) { return prefix + "gitlab.svg"; } else if (iconRef.contains("gogs")) { return prefix + "gogs.png"; } else if (iconRef.contains("grafana")) { return prefix + "grafana.png"; } else if (iconRef.contains("hubot-irc")) { return prefix + "hubot-irc.png"; } else if (iconRef.contains("hubot-letschat")) { return prefix + "hubot-letschat.png"; } else if (iconRef.contains("hubot-notifier")) { return prefix + "hubot-notifier.png"; } else if (iconRef.contains("hubot-slack")) { return prefix + "hubot-slack.png"; } else if (iconRef.contains("image-linker")) { return prefix + "image-linker.svg"; } else if (iconRef.contains("javascript")) { return prefix + "javascript.png"; } else if (iconRef.contains("java")) { return prefix + "java.svg"; } else if (iconRef.contains("jenkins")) { return prefix + "jenkins.svg"; } else if (iconRef.contains("jetty")) { return prefix + "jetty.svg"; } else if (iconRef.contains("karaf")) { return prefix + "karaf.svg"; } else if (iconRef.contains("keycloak")) { return prefix + "keycloak.svg"; } else if (iconRef.contains("kibana")) { return prefix + "kibana.svg"; } else if (iconRef.contains("kiwiirc")) { return prefix + "kiwiirc.png"; } else if (iconRef.contains("letschat")) { return prefix + "letschat.png"; } else if (iconRef.contains("mule")) { return prefix + "mule.svg"; } else if (iconRef.contains("nexus")) { return prefix + "nexus.png"; } else if (iconRef.contains("node")) { return prefix + "node.svg"; } else if (iconRef.contains("orion")) { return prefix + "orion.png"; } else if (iconRef.contains("prometheus")) { return prefix + "prometheus.png"; } else if (iconRef.contains("django") || iconRef.contains("python")) { return prefix + "python.png"; } else if (iconRef.contains("spring-boot")) { return prefix + "spring-boot.svg"; } else if (iconRef.contains("taiga")) { return prefix + "taiga.png"; } else if (iconRef.contains("tomcat")) { return prefix + "tomcat.svg"; } else if (iconRef.contains("tomee")) { return prefix + "tomee.svg"; } else if (iconRef.contains("vertx")) { return prefix + "vertx.svg"; } else if (iconRef.contains("wildfly")) { return prefix + "wildfly.svg"; } else if (iconRef.contains("wildfly-swarm")) { return prefix + "wildfly-swarm.png"; } else if (iconRef.contains("weld")) { return prefix + "weld.svg"; } else if (iconRef.contains("zipkin")) { return prefix + "zipkin.png"; } return null; } }