001: // THIS SOFTWARE IS PROVIDED BY SOFTARIS PTY.LTD. AND OTHER METABOSS
002: // CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
003: // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
004: // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTARIS PTY.LTD.
005: // OR OTHER METABOSS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
006: // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
007: // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
008: // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
009: // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
010: // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
011: // EVEN IF SOFTARIS PTY.LTD. OR OTHER METABOSS CONTRIBUTORS ARE ADVISED OF THE
012: // POSSIBILITY OF SUCH DAMAGE.
013: //
014: // Copyright 2000-2005 © Softaris Pty.Ltd. All Rights Reserved.
015: package com.metaboss.sdlctools.applications.anttasks.builder.modules;
016:
017: import java.io.File;
018: import java.util.ArrayList;
019: import java.util.Arrays;
020: import java.util.HashSet;
021: import java.util.Iterator;
022: import java.util.List;
023: import java.util.Set;
024:
025: import javax.jmi.reflect.JmiException;
026: import javax.naming.Context;
027: import javax.naming.InitialContext;
028: import javax.naming.NamingException;
029:
030: import org.apache.tools.ant.BuildException;
031:
032: import com.metaboss.enterprise.bs.BSException;
033: import com.metaboss.sdlctools.applications.anttasks.builder.MetaBossBuilderTask;
034: import com.metaboss.sdlctools.applications.anttasks.builder.ModuleDefinition;
035: import com.metaboss.sdlctools.applications.anttasks.builder.ToolInvocationDefinition;
036: import com.metaboss.sdlctools.applications.anttasks.builder.tools.*;
037: import com.metaboss.sdlctools.applications.anttasks.builder.tools.JarPackagerInvocationDefinition;
038: import com.metaboss.sdlctools.applications.anttasks.builder.tools.StorageImplementationGeneratorInvocationDefinition;
039: import com.metaboss.sdlctools.applications.anttasks.builder.tools.CoreCodeGeneratorInvocationDefinition;
040: import com.metaboss.sdlctools.applications.anttasks.builder.modules.subelements.IncludeStorageImplementationDefinition;
041: import com.metaboss.sdlctools.models.metabossmodel.ModelElement;
042: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.Enterprise;
043: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.Domain;
044: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.domainimplementationmodel.DomainRelationalStorageDefinition;
045: import com.metaboss.sdlctools.services.codegeneration.BSStorageImplementationGenerator;
046: import com.metaboss.sdlctools.services.codegeneration.CodeGenerationStylesheetAccessor;
047: import com.metaboss.sdlctools.services.codegenerationstylesheet.STDomainStylesheet;
048: import com.metaboss.sdlctools.services.codegenerationstylesheet.STEnterpriseStylesheet;
049: import com.metaboss.sdlctools.services.codegenerationstylesheet.STSystemStylesheet;
050: import com.metaboss.util.StringUtils;
051:
052: /** The definition of how to build system implementation module */
053: public class BusinessDomainsImplementationModuleDefinition extends
054: ModuleDefinition {
055: // Initialise metadata for supplying in the constructor
056: private static ElementMetadata sElementMetadata = new ElementMetadata();
057: static {
058: sElementMetadata.ElementTypeName = "BusinessDomainsImplementationModule";
059: sElementMetadata.SupportsModelElementRefs = true;
060: sElementMetadata.AllowedModelElementTypes = new Class[] {
061: Enterprise.class,
062: com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.System.class,
063: Domain.class };
064: }
065: private BSStorageImplementationGenerator mStorageImplementationGenerator = null;
066: private Set mDomainsToDo = new HashSet();
067: private List mStorageImplementationsToInclude = new ArrayList();
068: private Set mStorageDefinitionsToDo = new HashSet();
069: private String mDestinationArchiveName = null;
070:
071: /** The only available constructor */
072: public BusinessDomainsImplementationModuleDefinition(
073: MetaBossBuilderTask pOwnerTask) {
074: super (pOwnerTask, sElementMetadata);
075: }
076:
077: /** The special creator asking to include one or more storage implementations */
078: public IncludeStorageImplementationDefinition createIncludeStorageImplementation() {
079: IncludeStorageImplementationDefinition lIncludeDefinition = new IncludeStorageImplementationDefinition(
080: this );
081: mStorageImplementationsToInclude.add(lIncludeDefinition);
082: return lIncludeDefinition;
083: }
084:
085: /** Called when initialisation of parameters has been completed and generation is about to commence */
086: public void completeInitialisation() throws BuildException {
087: try {
088: // First obtain the storage implementation generator
089: Context lContext = new InitialContext();
090: mStorageImplementationGenerator = (BSStorageImplementationGenerator) lContext
091: .lookup(BSStorageImplementationGenerator.COMPONENT_URL);
092:
093: // Work on included module elements
094: ModelElement[] lIncludedModelElements = getIncludedModelElements();
095: // First collect list of al domains to generate implementations for
096: for (int lElementsIndex = 0; lElementsIndex < lIncludedModelElements.length; lElementsIndex++) {
097: ModelElement lIncludedModelElement = lIncludedModelElements[lElementsIndex];
098: mDomainsToDo.addAll(Arrays.asList(getOwnerTask()
099: .findModelElementsByXPath(
100: lIncludedModelElement,
101: "descendant-or-self::Domain",
102: new Class[] { Domain.class })));
103: }
104:
105: // Work on the module name
106: String lModuleName = getModuleName();
107: if (lModuleName == null) {
108: ModelElement lRootModelElement = getRootModelElement();
109: if (lRootModelElement instanceof Domain) {
110: // Set up module name for the domain
111: STDomainStylesheet lDomainStylesheet = CodeGenerationStylesheetAccessor
112: .getDomainStylesheet(lRootModelElement
113: .getRef());
114: lModuleName = lDomainStylesheet
115: .getBusinessDomainImplementationModuleName();
116: } else if (lRootModelElement instanceof com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.System) {
117: // Set up module name for the system
118: STSystemStylesheet lSystemStylesheet = CodeGenerationStylesheetAccessor
119: .getSystemStylesheet(lRootModelElement
120: .getRef());
121: lModuleName = lSystemStylesheet
122: .getBusinessDomainImplementationModuleName();
123: } else if (lRootModelElement instanceof Enterprise) {
124: // Set up module name for the domain
125: STEnterpriseStylesheet lEntepriseStylesheet = CodeGenerationStylesheetAccessor
126: .getEnterpriseStylesheet(lRootModelElement
127: .getName());
128: lModuleName = lEntepriseStylesheet
129: .getBusinessDomainImplementationModuleName();
130: }
131: }
132: // We now have a automatically generated modules name. Se if we need to use it or the explicit one
133: StringBuffer lModuleNameBuffer = new StringBuffer(
134: lModuleName);
135: // Finish building the archive name
136: String lVersionToken = getOwnerTask().getVersionToken();
137: if (lVersionToken != null) {
138: lModuleNameBuffer.append("_");
139: lModuleNameBuffer.append(lVersionToken);
140: }
141: lModuleNameBuffer.append(".jar");
142: mDestinationArchiveName = lModuleNameBuffer.toString();
143:
144: // Now complete initialisation and collect list of storage implementations to include
145: for (Iterator lIncludedIterator = mStorageImplementationsToInclude
146: .iterator(); lIncludedIterator.hasNext();) {
147: IncludeStorageImplementationDefinition lInclusionDefinitionElement = (IncludeStorageImplementationDefinition) lIncludedIterator
148: .next();
149: lInclusionDefinitionElement
150: .setDefaultRootModelElement(getRootModelElement());
151: lInclusionDefinitionElement.completeInitialisation();
152: DomainRelationalStorageDefinition[] lIncludedStorages = lInclusionDefinitionElement
153: .getIncludedStorages();
154: // Need to check if this storage definition belongs to one of the included domains and collect the list of them
155: for (int i = 0; i < lIncludedStorages.length; i++) {
156: DomainRelationalStorageDefinition lIncludedStorage = lIncludedStorages[i];
157: if (!mDomainsToDo.contains(lIncludedStorage
158: .getDomain()))
159: throw new BuildException(
160: "The <IncludeStorageImplementation> subelement must refer to the StorageImplementation contained within one of the referenced Domains");
161: mStorageDefinitionsToDo.add(lIncludedStorage);
162: }
163: }
164: } catch (NamingException e) {
165: throw new BuildException(
166: "Unable to locate generator for the Domain Implementation. Caught NamingException: "
167: + e.getMessage());
168: } catch (JmiException e) {
169: throw new BuildException(
170: "Caught exception while preparing to build module. "
171: + e.getMessage());
172: } catch (BSException e) {
173: throw new BuildException(
174: "Caught exception while preparing to build module. "
175: + e.getMessage());
176: }
177: }
178:
179: // Returns plan to invoke any number of code generators necessary to build the module
180: public ToolInvocationDefinition[] getGenerationPlan() {
181: try {
182: List lInvocations = new ArrayList();
183: // First generate system core
184: for (Iterator lDomainsIterator = mDomainsToDo.iterator(); lDomainsIterator
185: .hasNext();) {
186: Domain lDomain = (Domain) lDomainsIterator.next();
187: CoreCodeGeneratorInvocationDefinition lSystemCoreGeneratorInvocationDefinition = new CoreCodeGeneratorInvocationDefinition(
188: getOwnerTask());
189: lSystemCoreGeneratorInvocationDefinition
190: .setSystemRef(lDomain.getSystem().getRef());
191: lInvocations
192: .add(lSystemCoreGeneratorInvocationDefinition);
193: // Immediately compile data types because some other tools might use them
194: if (getOwnerTask().getTypesSrcDir() != null) {
195: // Compile custom enterprise types
196: lInvocations
197: .add(JavaCompilerInvocationDefinitionUtils
198: .createForCustomEnterpriseTypes(
199: this , lDomain.getSystem()
200: .getEnterprise()));
201: // Compile ciustom generated system types
202: lInvocations
203: .add(JavaCompilerInvocationDefinitionUtils
204: .createForCustomSystemTypes(this ,
205: lDomain.getSystem()));
206: }
207: // Compile generated enterprise types
208: lInvocations.add(JavaCompilerInvocationDefinitionUtils
209: .createForEnterpriseTypes(this , lDomain
210: .getSystem().getEnterprise()));
211: // Compile generated system types
212: lInvocations
213: .add(JavaCompilerInvocationDefinitionUtils
214: .createForSystemTypes(this , lDomain
215: .getSystem()));
216: }
217: // Now generate storage definitions
218: for (Iterator lStorageDefinitionsIterator = mStorageDefinitionsToDo
219: .iterator(); lStorageDefinitionsIterator.hasNext();) {
220: DomainRelationalStorageDefinition lStorageDefinition = (DomainRelationalStorageDefinition) lStorageDefinitionsIterator
221: .next();
222: // Generate storage code
223: StorageImplementationGeneratorInvocationDefinition lStorageImplementationGeneratorInvocationDefinition = new StorageImplementationGeneratorInvocationDefinition(
224: getOwnerTask());
225: lStorageImplementationGeneratorInvocationDefinition
226: .setGenerator(mStorageImplementationGenerator);
227: lStorageImplementationGeneratorInvocationDefinition
228: .setDomainRelationalStorageDefinition(lStorageDefinition);
229: lInvocations
230: .add(lStorageImplementationGeneratorInvocationDefinition);
231: }
232: // Return what we have
233: return (ToolInvocationDefinition[]) lInvocations
234: .toArray(new ToolInvocationDefinition[lInvocations
235: .size()]);
236: } catch (JmiException e) {
237: throw new BuildException(
238: "Caught exception while generating the build plan. "
239: + e.getMessage());
240: } catch (BSException e) {
241: throw new BuildException(
242: "Caught exception while generating the build plan. "
243: + e.getMessage());
244: }
245: }
246:
247: // Returns tasks to do after generation. (Normally compillation would go in here
248: public ToolInvocationDefinition[] getCompilationPlan() {
249: try {
250: List lInvocations = new ArrayList();
251: // Compile parts of the core
252: for (Iterator lDomainsIterator = mDomainsToDo.iterator(); lDomainsIterator
253: .hasNext();) {
254: Domain lDomain = (Domain) lDomainsIterator.next();
255: // Will need to compile enterprise types
256: lInvocations.add(JavaCompilerInvocationDefinitionUtils
257: .createForEnterpriseTypes(this , lDomain
258: .getSystem().getEnterprise()));
259: // Will need to compile system types
260: lInvocations
261: .add(JavaCompilerInvocationDefinitionUtils
262: .createForSystemTypes(this , lDomain
263: .getSystem()));
264: // Domain interfaces
265: lInvocations.add(JavaCompilerInvocationDefinitionUtils
266: .createForDomainInterfaces(this , lDomain));
267: // Storage interfaces
268: lInvocations.add(JavaCompilerInvocationDefinitionUtils
269: .createForStorageInterfaces(this , lDomain));
270: // Domain implementations interfaces
271: lInvocations.add(JavaCompilerInvocationDefinitionUtils
272: .createForDomainImplementation(this , lDomain));
273: }
274: // Now generate code for included storage implementations
275: for (Iterator lStorageDefinitionsIterator = mStorageDefinitionsToDo
276: .iterator(); lStorageDefinitionsIterator.hasNext();) {
277: DomainRelationalStorageDefinition lStorageDefinition = (DomainRelationalStorageDefinition) lStorageDefinitionsIterator
278: .next();
279: lInvocations.add(JavaCompilerInvocationDefinitionUtils
280: .createForStorageImplementation(this ,
281: lStorageDefinition,
282: mStorageImplementationGenerator));
283: }
284: // Return what we have
285: return (ToolInvocationDefinition[]) lInvocations
286: .toArray(new ToolInvocationDefinition[lInvocations
287: .size()]);
288: } catch (BSException e) {
289: throw new BuildException(
290: "Caught exception while generating packaging plan. "
291: + e.getMessage());
292: }
293: }
294:
295: // Returns tasks to invoke any number of packagers necessary to build the module
296: public ToolInvocationDefinition[] getPackagingPlan() {
297: try {
298: JarPackagerInvocationDefinition lJarPackager = new JarPackagerInvocationDefinition(
299: getOwnerTask());
300: lJarPackager.setDestFileName(mDestinationArchiveName);
301: // There may be some additional files to include
302: lJarPackager.addFileSetIncludes(getAdditionalFiles());
303:
304: // Compile parts of the core
305: for (Iterator lDomainsIterator = mDomainsToDo.iterator(); lDomainsIterator
306: .hasNext();) {
307: Domain lDomain = (Domain) lDomainsIterator.next();
308: com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.System lSystem = lDomain
309: .getSystem();
310: STDomainStylesheet lDomainStylesheet = CodeGenerationStylesheetAccessor
311: .getDomainStylesheet(lDomain);
312: // Domain interfaces
313: String lDomainInterfacePackage = lDomainStylesheet
314: .getDomainPackageName();
315: String lDomainInterfaceSubdirectory = StringUtils
316: .replace(lDomainInterfacePackage, ".",
317: File.separator);
318: lJarPackager
319: .addClassInclude(lDomainInterfaceSubdirectory
320: + File.separator + "*.*");
321: // Storage interfaces
322: String lStorageInterfacePackage = lDomainStylesheet
323: .getStoragePackageName();
324: String lStorageInterfaceSubdirectory = StringUtils
325: .replace(lStorageInterfacePackage, ".",
326: File.separator);
327: lJarPackager
328: .addClassInclude(lStorageInterfaceSubdirectory
329: + File.separator + "*.*");
330: // Domain implementations interfaces
331: String lDomainImplementationPackage = lDomainStylesheet
332: .getImplementationPackageName();
333: String lDomainImplementationSubdirectory = StringUtils
334: .replace(lDomainImplementationPackage, ".",
335: File.separator);
336: lJarPackager
337: .addClassInclude(lDomainImplementationSubdirectory
338: + File.separator + "*.*");
339: }
340: // Now generate code for included storage implementations
341: for (Iterator lStorageDefinitionsIterator = mStorageDefinitionsToDo
342: .iterator(); lStorageDefinitionsIterator.hasNext();) {
343: DomainRelationalStorageDefinition lStorageDefinition = (DomainRelationalStorageDefinition) lStorageDefinitionsIterator
344: .next();
345: String lStorageImplementationPackage = mStorageImplementationGenerator
346: .getImplementationPackageName(lStorageDefinition
347: .getRef());
348: String lStorageImplementationSubdirectory = StringUtils
349: .replace(lStorageImplementationPackage, ".",
350: File.separator);
351: lJarPackager
352: .addClassInclude(lStorageImplementationSubdirectory
353: + File.separator
354: + "**"
355: + File.separator + "*.*");
356: }
357: // Return what we have
358: return new ToolInvocationDefinition[] { lJarPackager };
359: } catch (BSException e) {
360: throw new BuildException(
361: "Caught exception while generating packaging plan. "
362: + e.getMessage());
363: }
364: }
365: }
|