001/* 002 * Copyright 2012-2016 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.boot.ant; 018 019import java.io.File; 020import java.io.IOException; 021import java.util.jar.JarFile; 022 023import org.apache.tools.ant.BuildException; 024import org.apache.tools.ant.Project; 025import org.apache.tools.ant.Task; 026 027import org.springframework.boot.loader.tools.MainClassFinder; 028import org.springframework.util.StringUtils; 029 030/** 031 * Ant task to find a main class. 032 * 033 * @author Matt Benson 034 * @since 1.3.0 035 */ 036public class FindMainClass extends Task { 037 038 private static final String SPRING_BOOT_APPLICATION_CLASS_NAME = "org.springframework.boot.autoconfigure.SpringBootApplication"; 039 040 private String mainClass; 041 042 private File classesRoot; 043 044 private String property; 045 046 public FindMainClass(Project project) { 047 setProject(project); 048 } 049 050 @Override 051 public void execute() throws BuildException { 052 String mainClass = this.mainClass; 053 if (!StringUtils.hasText(mainClass)) { 054 mainClass = findMainClass(); 055 if (!StringUtils.hasText(mainClass)) { 056 throw new BuildException( 057 "Could not determine main class given @classesRoot " 058 + this.classesRoot); 059 } 060 } 061 handle(mainClass); 062 } 063 064 private String findMainClass() { 065 if (this.classesRoot == null) { 066 throw new BuildException( 067 "one of @mainClass or @classesRoot must be specified"); 068 } 069 if (!this.classesRoot.exists()) { 070 throw new BuildException( 071 "@classesRoot " + this.classesRoot + " does not exist"); 072 } 073 try { 074 if (this.classesRoot.isDirectory()) { 075 return MainClassFinder.findSingleMainClass(this.classesRoot, 076 SPRING_BOOT_APPLICATION_CLASS_NAME); 077 } 078 return MainClassFinder.findSingleMainClass(new JarFile(this.classesRoot), "/", 079 SPRING_BOOT_APPLICATION_CLASS_NAME); 080 } 081 catch (IOException ex) { 082 throw new BuildException(ex); 083 } 084 } 085 086 private void handle(String mainClass) { 087 if (StringUtils.hasText(this.property)) { 088 getProject().setProperty(this.property, mainClass); 089 } 090 else { 091 log("Found main class " + mainClass); 092 } 093 } 094 095 /** 096 * Set the main class, which will cause the search to be bypassed. 097 * @param mainClass the main class name 098 */ 099 public void setMainClass(String mainClass) { 100 this.mainClass = mainClass; 101 } 102 103 /** 104 * Set the root location of classes to be searched. 105 * @param classesRoot the root location 106 */ 107 public void setClassesRoot(File classesRoot) { 108 this.classesRoot = classesRoot; 109 } 110 111 /** 112 * Set the ANT property to set (if left unset, result will be printed to the log). 113 * @param property the ANT property to set 114 */ 115 public void setProperty(String property) { 116 this.property = property; 117 } 118 119}