/* * Copyright 2008-2010 Xebia and the original author or authors. * * 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 fr.xebia.management.maven; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.IOException; import java.net.URISyntaxException; import java.util.Arrays; import java.util.Properties; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import javax.servlet.ServletContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.InitializingBean; import org.springframework.jmx.export.annotation.ManagedAttribute; import org.springframework.jmx.export.annotation.ManagedResource; import org.springframework.jmx.export.naming.SelfNaming; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.web.context.ServletContextAware; /** * Maven project information (groupId, artifactId, version) exposed with JMX. * * @author <a href="mailto:cyrille@cyrilleleclerc.com">Cyrille Le Clerc</a> */ @ManagedResource public class WebApplicationMavenInformation implements ServletContextAware, InitializingBean, SelfNaming, BeanNameAware { private static class DirectoryFileFilter implements FileFilter { public boolean accept(File file) { return file.isDirectory(); } } private static final String POM_PROPERTY_ARTIFACT_ID = "artifactId"; private static final String POM_PROPERTY_GROUP_ID = "groupId"; private static final String POM_PROPERTY_VERSION = "version"; private String artifactId = "#UNKNOWN#"; private String beanName; private String groupId = "#UNKNOWN#"; private String jmxDomain = "fr.xebia"; protected final Logger logger = LoggerFactory.getLogger(WebApplicationMavenInformation.class); private ObjectName objectName; private ServletContext servletContext; private String version = "#UNKNOWN#"; public void afterPropertiesSet() throws Exception { Assert.notNull(this.servletContext, "'servletConfig' can not be null"); loadInformationFromPomProperties(); } @ManagedAttribute(description = "Maven ${project.artifactId} property extracted from " + "${webapp-home}/META-INF/${groupId}/${artifactId}/pom.properties file") public String getArtifactId() { return artifactId; } @ManagedAttribute(description = "Maven ${project.groupId}:${project.artifactId}:${project.version} properties " + "extracted from ${webapp-home}/META-INF/${groupId}/${artifactId}/pom.properties file") public String getFullyQualifiedArtifactIdentifier() { return groupId + ":" + artifactId + ":" + version; } @ManagedAttribute(description = "Maven ${project.groupId} property extracted from " + "${webapp-home}/META-INF/${groupId}/${artifactId}/pom.properties file") public String getGroupId() { return groupId; } public ObjectName getObjectName() throws MalformedObjectNameException { if (objectName == null) { String objectNameString = jmxDomain + ":type=WebApplicationMavenInformation"; if (StringUtils.hasText(this.beanName)) { objectNameString += ",name=" + ObjectName.quote(this.beanName); } objectName = ObjectName.getInstance(objectNameString); } return objectName; } @ManagedAttribute(description = "Maven ${project.version} property extracted from " + "${webapp-home}/META-INF/${groupId}/${artifactId}/pom.properties file") public String getVersion() { return version; } private void loadInformationFromPomProperties() throws URISyntaxException, IOException { String mavenMetaInfFolderPath = servletContext.getRealPath("/META-INF/maven/"); if (mavenMetaInfFolderPath == null) { logger.warn("Folder " + servletContext.getRealPath("/") + "/META-INF/maven/" + " not found. Application probably in development mode, could not determine application maven information"); return; } File mavenMetaInfFolder = new File(mavenMetaInfFolderPath); if (!mavenMetaInfFolder.exists()) { logger.warn("Folder " + mavenMetaInfFolder.getAbsolutePath() + " not found. Application probably in development mode, could not determine application maven information"); return; } File[] groupIdFolderAsArray = mavenMetaInfFolder.listFiles(new DirectoryFileFilter()); if (groupIdFolderAsArray.length == 0) { logger.warn("Folder /META-INF/maven/${project.groupId} not found under " + mavenMetaInfFolder.getAbsolutePath() + ". Application probably in development mode, could not determine application maven information"); return; } else if (groupIdFolderAsArray.length > 1) { logger.warn("More than one folder found under " + mavenMetaInfFolder.getAbsolutePath() + " : " + Arrays.asList(groupIdFolderAsArray) + ". Could not determine application maven information"); return; } File groupIdFolder = groupIdFolderAsArray[0]; File[] artifactIdFolderAsArray = groupIdFolder.listFiles(new DirectoryFileFilter()); if (artifactIdFolderAsArray.length == 0) { logger.warn("Folder /META-INF/maven/" + groupIdFolder.getName() + "/${project.artifactId} not found under " + mavenMetaInfFolder.getAbsolutePath() + ". Application probably in development mode, could not determine application maven information"); return; } else if (artifactIdFolderAsArray.length > 1) { logger.warn("More than one folder found under " + groupIdFolder.getAbsolutePath() + " : " + Arrays.asList(artifactIdFolderAsArray) + ". Could not determine application maven information"); return; } File artifactIdFolder = artifactIdFolderAsArray[0]; File pomPropertiesFile = new File(artifactIdFolder, "pom.properties"); if (!pomPropertiesFile.exists()) { logger.warn("File " + pomPropertiesFile.getAbsolutePath() + " not found. Application probably in development mode, could not determine application maven information"); return; } Properties pomProperties = new Properties(); FileInputStream in = new FileInputStream(pomPropertiesFile); try { pomProperties.load(in); } finally { in.close(); } this.groupId = pomProperties.getProperty(POM_PROPERTY_GROUP_ID, this.groupId); this.artifactId = pomProperties.getProperty(POM_PROPERTY_ARTIFACT_ID, this.artifactId); this.version = pomProperties.getProperty(POM_PROPERTY_VERSION, this.version); } public void setBeanName(String name) { this.beanName = name; } public void setJmxDomain(String jmxDomain) { this.jmxDomain = jmxDomain; } public void setObjectName(String objectName) throws MalformedObjectNameException { if (objectName == null) { this.objectName = null; } else { this.objectName = ObjectName.getInstance(objectName); } } public void setServletContext(ServletContext servletContext) { this.servletContext = servletContext; } }