package org.wirsind.info;
import hudson.FilePath;
import hudson.Launcher;
import hudson.Proc;
import hudson.util.ArgumentListBuilder;
import hudson.util.FormFieldValidator;
import hudson.model.AbstractBuild;
import hudson.model.Build;
import hudson.model.BuildListener;
import hudson.model.Descriptor;
import hudson.tasks.Builder;
import hudson.tasks.CommandInterpreter;
import net.sf.json.JSONObject;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.QueryParameter;
import com.sun.org.apache.bcel.internal.generic.IF_ICMPGE;
import javax.servlet.ServletException;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Sample {@link Builder}.
*
* <p>
* When the user configures the project and enables this builder,
* {@link DescriptorImpl#newInstance(StaplerRequest)} is invoked
* and a new {@link RhapsodyBuilder} is created. The created
* instance is persisted to the project configuration XML by using
* XStream, so this allows you to use instance fields (like {@link #name})
* to remember the configuration.
*
* <p>
* When a build is performed, the {@link #perform(Build, Launcher, BuildListener)} method
* will be invoked.
*
* @author Markus Hoffmann
*/
public class RhapsodyBuilder extends Builder {
private final String components;
private String projectPath;
private final String rhapsodyConfiguration;
private final boolean generate;
private final boolean make;
@DataBoundConstructor
public RhapsodyBuilder(String components, String projectPath, String rhapsodyConfiguration, boolean generate, boolean make) {
this.components = components;
this.projectPath = projectPath;
this.rhapsodyConfiguration = rhapsodyConfiguration;
this.generate = generate;
this.make = make;
}
public String getProjectPath()
{
return projectPath;
}
public String getComponents()
{
return components;
}
public String getRhapsodyConfiguration()
{
return rhapsodyConfiguration;
}
public boolean getGenerate()
{
return generate;
}
public boolean getMake()
{
return make;
}
@Override
public boolean prebuild(AbstractBuild<?, ?> build, BuildListener listener)
{
// TODO Auto-generated method stub
/*try {
build.getExecutor().sleep(100000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
return true;
}
public boolean perform(Build build, Launcher launcher, BuildListener listener) {
// resolving hudson variables for the properties set
Map<String, String> envVars = build.getEnvVars();
Set<String> keys = envVars.keySet();
for (String key : keys) {
this.projectPath = this.projectPath.replaceAll("\\$" + key, envVars.get(key));
this.projectPath = this.projectPath.replaceAll("\\$\\{" + key + "\\}", envVars.get(key));
}
// split the components entered in the component field
String[] componentList = this.components.split(",");
String rhapsodyCall = DESCRIPTOR.rhapsodyClPath() + " -cmd=open " + this.projectPath;
for (int i=0; i < componentList.length; ++i)
{
if (generate)
{
rhapsodyCall += " -cmd=setcomponent " + componentList[i];
rhapsodyCall += " -cmd=setconfiguration " + this.rhapsodyConfiguration + " -cmd=regenerate";
if (make)
{
rhapsodyCall += " -cmd=syncmake";
}
}
}
rhapsodyCall += " -cmd=exit \n";
Map<String, String> system =System.getenv();
List<String> param = new ArrayList<String>();
for (Map.Entry<String, String> entry : system.entrySet()) {
String s = entry.getKey() + "=" + entry.getValue();
param.add(s);
}
if (DESCRIPTOR.licenseServerPath()!=null) {
param.add("LM_LICENSE_FILE=" + DESCRIPTOR.licenseServerPath());
}
String[] env = param.toArray(new String[param.size()]);
int returnValue;
try {
Proc proc = launcher.launch(rhapsodyCall, env, listener.getLogger(), build.getProject().getWorkspace());
returnValue = proc.join();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
listener.getLogger().println("IOException !");
return false;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
listener.getLogger().println("InterruptedException !");
return false;
}
if (returnValue == 0)
return true;
else
return false;
}
public Descriptor<Builder> getDescriptor() {
// see Descriptor javadoc for more about what a descriptor is.
return DESCRIPTOR;
}
/**
* Descriptor should be singleton.
*/
public static final DescriptorImpl DESCRIPTOR = new DescriptorImpl();
/**
* Descriptor for {@link RhapsodyBuilder}. Used as a singleton.
* The class is marked as public so that it can be accessed from views.
*
* <p>
* See <tt>views/hudson/plugins/hello_world/RhapsodyBuilder/*.jelly</tt>
* for the actual HTML fragment for the configuration screen.
*/
public static final class DescriptorImpl extends Descriptor<Builder> {
private String rhapsodyClPath;
private String licenseServerPath;
DescriptorImpl() {
super(RhapsodyBuilder.class);
load();
}
public String rhapsodyClPath() {
return rhapsodyClPath;
}
public String licenseServerPath() {
return licenseServerPath;
}
/**
* Performs on-the-fly validation of the form field 'name'.
*
* @param value
* This receives the current value of the field.
*/
public void doCheckProjectPath(StaplerRequest req, StaplerResponse rsp, @QueryParameter final String value) throws IOException, ServletException {
new FormFieldValidator(req,rsp,null) {
/**
* The real check goes here. In the end, depending on which
* method you call, the browser shows text differently.
*/
protected void check() throws IOException, ServletException {
if(value.length()==0)
error("please set the path to the Rhapsody Project !");
else
if(value.length()<4)
warning("isn't the path too short?");
else {
File file = new File(value);
if (file.isDirectory()) {
error("you entered a directory please select the *.rpy file !");
} else
//TODO add more checks
ok();
}
}
}.process();
}
/**
* Performs on-the-fly validation of the form field 'name'.
*
* @param value
* This receives the current value of the field.
*/
public void doCheckComponents(StaplerRequest req, StaplerResponse rsp, @QueryParameter final String value) throws IOException, ServletException {
new FormFieldValidator(req,rsp,null) {
/**
* The real check goes here. In the end, depending on which
* method you call, the browser shows text differently.
*/
protected void check() throws IOException, ServletException {
if(value.length()==0)
error("please specify at least one component");
else {
//TODO add more checks
ok();
}
}
}.process();
}
/**
* Performs on-the-fly validation of the form field 'name'.
*
* @param value
* This receives the current value of the field.
*/
public void doCheckRhapsodyConfiguration(StaplerRequest req, StaplerResponse rsp, @QueryParameter final String value) throws IOException, ServletException {
new FormFieldValidator(req,rsp,null) {
/**
* The real check goes here. In the end, depending on which
* method you call, the browser shows text differently.
*/
protected void check() throws IOException, ServletException {
if(value.length()==0)
error("please specify a configuration");
else {
//TODO add more checks
ok();
}
}
}.process();
}
/**
* Performs on-the-fly validation of the form field 'licenseServerPath'.
*
* @param value
* This receives the license server address or the path to the license file of Rhapsody.
*/
public void doCheckLicenseServerPath(StaplerRequest req, StaplerResponse rsp, @QueryParameter final String value) throws IOException, ServletException {
new FormFieldValidator(req,rsp,null) {
/**
* The real check goes here. In the end, depending on which
* method you call, the browser shows text differently.
*/
protected void check() throws IOException, ServletException {
if(value.length()==0)
error("please type in the License Server");
else {
//TODO add more checks
ok();
}
}
}.process();
}
/**
* Performs on-the-fly validation of the form field 'rhapsodyCLPath'.
*
* @param value
* This receives the path to the executable rhapsodyCL.exe
*/
public void doCheckRhapsodyClPath(StaplerRequest req, StaplerResponse rsp, @QueryParameter final String value) throws IOException, ServletException {
new FormFieldValidator(req,rsp,null) {
/**
* The real check goes here. In the end, depending on which
* method you call, the browser shows text differently.
*/
protected void check() throws IOException, ServletException {
if(value.length()==0)
error("please specify the path to the RhapsodyCL.exe file");
else if(!value.contains("RhapsodyCL.exe")) {
error("didn't find RhapsodyCL.exe in the path !");
}else{
ok();
}
}
}.process();
}
/**
* This human readable name is used in the configuration screen.
*/
public String getDisplayName() {
return "Rhapsody Build";
}
public boolean configure(StaplerRequest req, JSONObject o) throws FormException {
// to persist global configuration information,
rhapsodyClPath = o.getString("rhapsodyClPath");
licenseServerPath = o.getString("licenseServerPath");
save();
return super.configure(req, o);
}
}
}