KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > beehive > controls > runtime > assembly > AssembleTask


1 package org.apache.beehive.controls.runtime.assembly;
2
3 /*
4  * Copyright 2004 The Apache Software Foundation.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * $Header:$
19  */

20
21 import java.io.File JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.util.ArrayList JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.Map JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.Set JavaDoc;
28 import java.util.TreeSet JavaDoc;
29 import java.net.URL JavaDoc;
30 import java.net.URLClassLoader JavaDoc;
31
32 import org.apache.tools.ant.BuildException;
33 import org.apache.tools.ant.Task;
34 import org.apache.tools.ant.types.Path;
35 import org.apache.tools.ant.types.FileSet;
36 import org.apache.beehive.controls.runtime.generator.apt.ControlClientManifest;
37 import org.apache.beehive.controls.api.assembly.ControlAssemblyException;
38
39 /**
40  * AssembleTask defines a custom ant task to perform control assembly.
41  * <p>
42  * The core assembly algorithm is documented and implemented in {@link Assembler}.
43  * <p>
44  * Required attributes:<br>
45  * <b>moduleDir</b>: path to the root of J2EE module on which to perform assembly.<br>
46  * <b>srcOutputDir</b>: path to the dir where control assemblers may output source files.
47  * It may be necessary to run additional build steps in order to process such files (for example,
48  * if an assembler outputs Java source code, that code may need to be compiled).<br>
49  * <b>contextFactoryClassname</b>: fully qualified classname of a factory class that implements
50  * {@link org.apache.beehive.controls.api.assembly.ControlAssemblyContext$Factory}. Typically this
51  * would depend on the type of module on which assembly is being run (EJB, webapp, etc). Different
52  * contexts will expose different APIs to control assemblers (making different descriptors available,
53  * etc).
54  * <p>
55  * Supported nested elements:<br>
56  * <b>classpath</b>: specifies the classpath that will be searched for control interfaces/implementations,
57  * control clients and control assemblers.<br>
58  * <b>fileset</b>: specifies the control client manifests that should be processed by this assembly call.<br>
59  * <p>
60  * An example usage of the AssembleTask in an ant build script (build.xml):
61  * <p>
62 <xmp>
63  <taskdef name="assemble" classname="org.apache.beehive.controls.runtime.assembly.AssembleTask"
64              classpathref="controls.dependency.path" onerror="report" />
65
66  <assemble moduleDir="${build.beans}"
67            srcOutputDir="${build.beansrc}"
68            contextFactoryClassname="org.apache.beehive.controls.runtime.assembly.EJBAssemblyContext$Factory">
69      <classpath>
70         <path refid="test.classpath"/>
71         <pathelement location="${build.beans}"/>
72      </classpath>
73      <fileset dir="${build.beans}">
74          <include name="**\*.controls.properties"/>
75      </fileset>
76  </assemble>
77 </xmp>
78  */

79 public class AssembleTask extends Task
80 {
81     public AssembleTask()
82     {
83         // do nothing
84
}
85
86     public void setContextFactoryClassName(String JavaDoc contextFactoryClassName)
87     {
88         _contextFactoryClassName = contextFactoryClassName;
89     }
90
91     public void setModuleDir( File JavaDoc moduleDir )
92     {
93         _moduleDir = moduleDir;
94     }
95
96     public void setModuleName( String JavaDoc moduleName )
97     {
98         _moduleName = moduleName;
99     }
100
101     public void setSrcOutputDir( File JavaDoc srcOutputDir )
102     {
103         _srcOutputDir = srcOutputDir;
104     }
105
106     public void setBindingFile(File JavaDoc bindingFile)
107     {
108         _bindingFile = bindingFile;
109     }
110
111     public FileSet createFileset()
112     {
113         _clientManifestFileSet = new FileSet();
114         return _clientManifestFileSet;
115     }
116
117     // used to set classpath as an attribute
118
public void setClasspath(Path classpath)
119     {
120         _classPath = new Path(getProject());
121         _classPath.append(classpath);
122     }
123
124     // used to set classpath as a nested element
125
public Path createClasspath()
126     {
127         _classPath = new Path(getProject());
128         return _classPath;
129     }
130
131     public void execute()
132     {
133         validateAttributeSettings();
134
135         if (_clientManifestFileSet == null)
136         {
137             log("No input fileset specified, nothing to do.");
138             return;
139         }
140
141         // get list of input files as list of ControlRefs files
142
File JavaDoc filesetDir = _clientManifestFileSet.getDir(getProject());
143         String JavaDoc[] clientManifests = _clientManifestFileSet.
144             getDirectoryScanner(getProject()).getIncludedFiles();
145
146         if (clientManifests.length == 0)
147         {
148             log("Input fileset contained no files, nothing to do.");
149             return;
150         }
151
152         List JavaDoc<File JavaDoc> manifestFiles = new ArrayList JavaDoc<File JavaDoc>();
153         for ( String JavaDoc mf : clientManifests )
154         {
155             File JavaDoc f = new File JavaDoc(filesetDir, mf );
156             if (!f.exists())
157             {
158                 log("File " + f.getAbsolutePath() +
159                         " in input fileset does not exist.");
160                 continue;
161             }
162
163             manifestFiles.add(f);
164         }
165
166         // REVIEW: nested control usage is handled poorly right now.
167
// Need to refine how we pick up control client manifests, especially
168
// for manifests inside control jars (instead of blindly scanning and
169
// including all manifests inside all jars, should base it on actual nested
170
// control usage as analyzed by starting at non-control clients).
171
try
172         {
173             // Build map of control types to assemble by scanning supplied manifests
174

175             Map JavaDoc<String JavaDoc,String JavaDoc> controlTypesToImpls = new HashMap JavaDoc<String JavaDoc,String JavaDoc>();
176             Map JavaDoc<String JavaDoc,Set JavaDoc<String JavaDoc>> controlTypesToClients =
177                 new HashMap JavaDoc<String JavaDoc, Set JavaDoc<String JavaDoc>>();
178
179             for ( File JavaDoc mf : manifestFiles )
180             {
181                 ControlClientManifest ccmf = new ControlClientManifest( mf );
182                 String JavaDoc controlClient = ccmf.getControlClient();
183                 List JavaDoc<String JavaDoc> controlTypes = ccmf.getControlTypes();
184                 for ( String JavaDoc ct : controlTypes )
185                 {
186                     controlTypesToImpls.put( ct, ccmf.getDefaultImpl( ct ) );
187                     Set JavaDoc<String JavaDoc> clients = controlTypesToClients.get( ct );
188                     if (clients == null)
189                     {
190                         clients = new TreeSet JavaDoc<String JavaDoc>();
191                         controlTypesToClients.put( ct, clients );
192                     }
193                     clients.add( controlClient );
194                 }
195             }
196
197             // Build classloader to do loading
198
//
199
// TODO: The module dir should probably be in the classpath, since it seems reasonable
200
// for assemblers to want access to the classes in the module.
201

202             String JavaDoc[] classpaths = _classPath == null ? new String JavaDoc[0] : _classPath.list();
203             ClassLoader JavaDoc cl = buildClassLoader( classpaths, Assembler.class.getClassLoader() );
204
205             Assembler.assemble( _moduleDir, _moduleName, _srcOutputDir, _contextFactoryClassName,
206                 controlTypesToImpls, controlTypesToClients, cl );
207         }
208         catch (Exception JavaDoc e)
209         {
210             e.printStackTrace();
211             throw new BuildException("Assembly failed.", e);
212         }
213     }
214
215     private void validateAttributeSettings() throws BuildException
216     {
217         if (_contextFactoryClassName == null)
218             throw new BuildException("The contextFactoryClassName attribute must be set");
219
220         if (_moduleDir == null)
221             throw new BuildException("The moduleDir attribute must be set");
222
223         if (_srcOutputDir == null)
224             throw new BuildException("The srcOutputDir attribute must be set");
225     }
226
227     private ClassLoader JavaDoc buildClassLoader( String JavaDoc[] paths, ClassLoader JavaDoc parentCL)
228         throws ControlAssemblyException
229     {
230         List JavaDoc list = new ArrayList JavaDoc();
231         for (int i=0; i<paths.length; i++)
232         {
233             try
234             {
235                 File JavaDoc file = new File JavaDoc(paths[i]);
236                 String JavaDoc filePath = file.getCanonicalPath();
237                 // ending slash is important for URLs that represent directories
238
if (!filePath.toLowerCase().endsWith(".jar") &&
239                     !filePath.endsWith("/") )
240                 {
241                     filePath += "/";
242                 }
243                 URL JavaDoc url = new URL JavaDoc("file:" + filePath);
244                 list.add(url);
245             }
246             catch (IOException JavaDoc e)
247             {
248                 throw new ControlAssemblyException("Unable to include path " +
249                     paths[i] + " in classpath. Caught " +
250                     e.getClass().getName() + " trying to form this path as a URL.", e);
251             }
252         }
253
254         URL JavaDoc[] urlArray = new URL JavaDoc[list.size()];
255         urlArray = (URL JavaDoc[])list.toArray(urlArray);
256
257         return new URLClassLoader JavaDoc(urlArray, parentCL);
258     }
259
260     // ant parameter values
261
protected String JavaDoc _contextFactoryClassName;
262     protected File JavaDoc _moduleDir;
263     protected String JavaDoc _moduleName;
264     protected File JavaDoc _srcOutputDir;
265     protected File JavaDoc _bindingFile;
266     protected Path _classPath;
267     protected FileSet _clientManifestFileSet;
268 }
269
Popular Tags