001 package com.hammurapi.config.bootstrap;
002
003 import java.net.URL;
004 import java.util.ArrayList;
005 import java.util.Collections;
006 import java.util.HashMap;
007 import java.util.List;
008 import java.util.Map;
009 import java.util.Properties;
010 import java.util.concurrent.Callable;
011 import java.util.concurrent.Executor;
012
013 import org.apache.tools.ant.BuildException;
014 import org.apache.tools.ant.Project;
015 import org.apache.tools.ant.Task;
016 import org.apache.tools.ant.taskdefs.Property;
017
018 import com.hammurapi.config.bootstrap.TokenExpander.TokenSource;
019
020 public class BootstrapTask extends Task {
021
022 private List<Property> properties = new ArrayList<Property>();
023
024 public void addProperty(Property property) {
025 properties.add(property);
026 }
027
028 private String codebase;
029
030 public void setCodebase(String codebase) {
031 this.codebase = codebase;
032 }
033
034 private String[] profile;
035
036 public void setProfile(String profile) {
037 this.profile = profile.split("/");
038 }
039
040 private boolean inheritAll;
041
042 public void setInheritAll(boolean inheritAll) {
043 this.inheritAll = inheritAll;
044 }
045
046 private String configUrl;
047
048 public void setConfigUrl(String configUrl) {
049 this.configUrl = configUrl;
050 }
051
052 private int threads;
053
054 /**
055 * Thread pool size.
056 * @param threads
057 */
058 public void setThreads(int threads) {
059 this.threads = threads;
060 }
061
062 @SuppressWarnings("unchecked")
063 @Override
064 public void execute() throws BuildException {
065 try {
066 final Properties props = new Properties();
067 if (inheritAll) {
068 props.putAll(getProject().getProperties());
069 }
070 for (Property property: properties) {
071 props.setProperty(property.getName(), property.getValue());
072 }
073
074 URL[] codebase = null;
075 if (this.codebase!=null) {
076 String[] cbs=this.codebase.split(";");
077 codebase = new URL[cbs.length];
078 for (int j=0; j<cbs.length; ++j) {
079 codebase[j] = new URL(cbs[j]);
080 }
081 }
082
083 if (configUrl==null) {
084 System.err.println("Invalid command line parameters - missing configuration URL.");
085 System.exit(1);
086 }
087
088 Bootstrapper<Object> factory = codebase==null ? new Bootstrapper<Object>() : new Bootstrapper<Object>(codebase);
089 TokenSource tokens = new TokenSource() {
090
091 public String getToken(String name) {
092 return props.getProperty(name);
093 }
094
095 };
096
097 SimpleThreadPool executor = threads>0 ? new SimpleThreadPool(threads) : null;
098
099 Map<Class<?>, Iterable<?>> services = new HashMap<Class<?>, Iterable<?>>();
100 if (executor!=null) {
101 services.put(Executor.class, Collections.singleton(executor));
102 }
103 services.put(Project.class, Collections.singletonList(this.getProject()));
104 FactoryClosure<Object> factoryClosure = factory.create(configUrl, tokens , profile, services, null);
105 Object result = factoryClosure.create();
106 try {
107 if (result instanceof Runnable) {
108 ((Runnable) result).run();
109 } else if (result instanceof Callable<?>) {
110 ((Callable) result).call();
111 } else {
112 throw new BuildException(result+" is not Runnable or Callable");
113 }
114 } finally {
115 Destroyable toDestroy=factoryClosure.getDestroyable();
116 if (toDestroy!=null) {
117 toDestroy.destroy();
118 }
119 factoryClosure=null;
120
121 if (executor!=null) {
122 executor.destroy();
123 }
124 }
125 } catch (BuildException e) {
126 throw e;
127 } catch (Exception e) {
128 throw new BuildException(e);
129 }
130 }
131
132 }