001: /*
002: * ====================================================================
003: * JAFFA - Java Application Framework For All
004: *
005: * Copyright (C) 2002 JAFFA Development Group
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: *
021: * Redistribution and use of this software and associated documentation ("Software"),
022: * with or without modification, are permitted provided that the following conditions are met:
023: * 1. Redistributions of source code must retain copyright statements and notices.
024: * Redistributions must also contain a copy of this document.
025: * 2. Redistributions in binary form must reproduce the above copyright notice,
026: * this list of conditions and the following disclaimer in the documentation
027: * and/or other materials provided with the distribution.
028: * 3. The name "JAFFA" must not be used to endorse or promote products derived from
029: * this Software without prior written permission. For written permission,
030: * please contact mail to: jaffagroup@yahoo.com.
031: * 4. Products derived from this Software may not be called "JAFFA" nor may "JAFFA"
032: * appear in their names without prior written permission.
033: * 5. Due credit should be given to the JAFFA Project (http://jaffa.sourceforge.net).
034: *
035: * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
039: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
040: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
041: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
042: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
043: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
044: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
045: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
046: * SUCH DAMAGE.
047: * ====================================================================
048: */
049: package org.jaffa.tools.patternmetaengine;
050:
051: import java.io.File;
052: import java.io.FileOutputStream;
053: import java.io.IOException;
054: import java.io.FileNotFoundException;
055: import java.util.List;
056: import java.util.Iterator;
057: import java.util.ArrayList;
058: import java.util.Properties;
059:
060: import javax.xml.bind.JAXBContext;
061: import javax.xml.bind.Validator;
062: import javax.xml.bind.ValidationException;
063: import javax.xml.bind.JAXBException;
064: import javax.xml.bind.Marshaller;
065: import javax.xml.bind.util.ValidationEventCollector;
066: import javax.xml.bind.ValidationEvent;
067:
068: import org.apache.log4j.Logger;
069: import org.jaffa.util.StringHelper;
070: import org.jaffa.datatypes.Defaults;
071: import org.jaffa.tools.patternmetaengine.domain.ApplicationBuilder;
072: import org.jaffa.tools.patternmetaengine.domain.Module;
073: import org.jaffa.patterns.library.domain_creator_1_1.domain.Field;
074: import org.jaffa.patterns.library.domain_creator_1_1.domain.Root;
075: import org.jaffa.patterns.library.object_lookup_meta_2_0.domain.*;
076: import java.io.StringWriter;
077: import java.io.BufferedOutputStream;
078: import java.io.ByteArrayOutputStream;
079: import java.beans.XMLEncoder;
080:
081: /**
082: *
083: * @author PaulE
084: */
085: public class BuildObjectLookup_2 implements IBuilder {
086:
087: /** Set up Logging for Log4J */
088: private static Logger log = Logger
089: .getLogger(BuildObjectLookup.class);
090:
091: private ApplicationBuilder m_app = null;
092: private Module m_module = null;
093: private Root m_domain = null;
094:
095: private ObjectLookupMeta m_lookup = null;
096: private Properties m_labels = null;
097:
098: private ComponentRegistry m_compReg = null;
099:
100: /** Creates a new instance of BuildObjectLookup */
101: public BuildObjectLookup_2(
102: ApplicationBuilder app,
103: ComponentRegistry comps,
104: Module module,
105: org.jaffa.patterns.library.domain_creator_1_1.domain.Root domain,
106: Properties labels) {
107:
108: log.debug("Create Lookup For - " + domain.getDomainObject());
109: m_compReg = comps;
110: m_app = app;
111: m_module = module;
112: m_domain = domain;
113: m_labels = labels;
114: }
115:
116: /** Causes the meta data object to be build ready for saving.
117: * @param fullPackage If true then the .applications. and .modules. package names
118: * are used. If this is false, these are ommited for a much more condensed package
119: * naming convention
120: */
121: public void buildPhase1(boolean fullPackage) throws Exception {
122: ObjectFactory objFactory = new ObjectFactory();
123: try {
124: m_lookup = objFactory.createObjectLookupMeta();
125: m_lookup
126: .setPatternTemplate("patterns/library/object_lookup_2_0/ObjectLookupPattern.xml"); // Mand
127: m_lookup.setApplication(m_app.getApplicationName()); // Mand
128: m_lookup.setModule(m_module.getName()); // Mand
129: m_lookup
130: .setComponent(m_domain.getDomainObject() + "Lookup"); // Mand
131: StringBuffer sb = new StringBuffer();
132: sb.append(m_app.getPackagePrefix());
133: sb.append(".");
134: if (fullPackage)
135: sb.append("applications.");
136: sb.append(m_app.getApplicationName());
137: sb.append(".");
138: if (fullPackage)
139: sb.append("modules.");
140: sb.append(m_module.getName());
141: m_lookup.setBasePackage(sb.toString().toLowerCase()); // Mand
142: m_lookup.setDomainObject(m_domain.getDomainObject()); // Mand
143: m_lookup.setDomainPackage(m_domain.getDomainPackage()); // Mand
144:
145: // Create Labels for the screen titles
146: String labelDomain = m_domain.getLabelToken();// get it from the domain object or fabricate it!
147: if (labelDomain == null)
148: labelDomain = "[label."
149: + StringHelper.getUpper1(m_app
150: .getApplicationName())
151: + "."
152: + StringHelper.getUpper1(m_module.getName())
153: + "."
154: + StringHelper.getUpper1(m_domain
155: .getDomainObject()) + "]";
156: String labelId = "title."
157: + StringHelper
158: .getUpper1(m_app.getApplicationName())
159: + "."
160: + StringHelper.getUpper1(m_module.getName())
161: + "."
162: + StringHelper
163: .getUpper1(m_domain.getDomainObject())
164: + "Lookup.";
165:
166: // Criteia Title
167: m_lookup.setCriteriaTitle("[" + labelId + "criteria" + "]"); // Opt
168: m_labels.put(labelId + "criteria", labelDomain
169: + " Lookup Criteria");
170: // Results Title
171: m_lookup.setResultsTitle("[" + labelId + "results" + "]"); // Opt
172: m_labels.put(labelId + "results", labelDomain + " Lookup");
173: // Add consolidated title
174: m_lookup.setConsolidatedCriteriaAndResultsTitle("["
175: + labelId + "consolidated" + "]"); // Opt;
176: m_labels.put(labelId + "consolidated", labelDomain
177: + " Lookup");
178:
179: // Add in tiles customizations of specified
180: if (m_module.getModuleTilePrefix() != null
181: && m_module.getModuleTilePrefix().length() > 0) {
182: m_lookup.setMainLayout(m_module.getModuleTilePrefix()
183: + ".MainLayout");
184: m_lookup.setLookupLayout(m_module.getModuleTilePrefix()
185: + ".LookupLayout");
186: }
187:
188: // Add All Fields as Criteria Fields
189: List fields = m_domain.getFields().getField();
190: if (fields == null || fields.isEmpty()) {
191: log
192: .error("Domain Object "
193: + m_domain.getDomainObject()
194: + " has no fields, this is needed to build a valid lookup");
195: } else {
196:
197: // Create Criteria Fields
198: CriteriaFields cfields = objFactory
199: .createCriteriaFields();
200: m_lookup.setCriteriaFields(cfields);
201: for (Iterator it1 = fields.iterator(); it1.hasNext();) {
202: Field fld = (Field) it1.next();
203:
204: CriteriaField cfld = objFactory
205: .createCriteriaField();
206: cfields.getCriteriaField().add(cfld);
207:
208: cfld.setName(reservedName(fld.getName()));
209:
210: String dt = Defaults.getDataType(fld.getDataType());
211: if (dt == null)
212: throw new Exception(
213: "Can't Translate Java Class "
214: + fld.getDataType()
215: + " to a supported Data Type");
216: cfld.setDataType(dt);
217:
218: cfld.setDisplay(true);
219: cfld.setDomainField(fld.getName());
220: //log.debug("Added Criteria Field : " + cfld.getName());
221: }
222:
223: // Create Results Fields
224: ResultsFields rfields = objFactory
225: .createResultsFields();
226: m_lookup.setResultsFields(rfields);
227: for (Iterator it1 = fields.iterator(); it1.hasNext();) {
228: Field fld = (Field) it1.next();
229:
230: ResultsField rfld = objFactory.createResultsField();
231: rfields.getResultsField().add(rfld);
232:
233: rfld.setName(reservedName(fld.getName()));
234: String dt = Defaults.getDataType(fld.getDataType());
235: if (dt == null)
236: throw new Exception(
237: "Can't Translate Java Class "
238: + fld.getDataType()
239: + " to a supported Data Type");
240: rfld.setDataType(dt);
241: rfld.setDisplay(true);
242: rfld
243: .setLabel(fld.getLabelToken() /*"[" + labelDomain + "." + fld.getName() + "]"*/);
244: rfld.setDomainField(fld.getName());
245: //log.debug("Added Result Field : " + rfld.getName());
246: }
247:
248: // Create Key Fields
249: KeyFields kfields = objFactory.createKeyFields();
250: m_lookup.setKeyFields(kfields);
251: for (Iterator it1 = fields.iterator(); it1.hasNext();) {
252: Field fld = (Field) it1.next();
253: if (fld.getPrimaryKey().equalsIgnoreCase("t")) {
254:
255: // This is a key field
256: KeyField kfld = objFactory.createKeyField();
257: kfields.getKeyField().add(kfld);
258:
259: kfld.setResultsFieldName(reservedName(fld
260: .getName()));
261: String dt = Defaults.getDataType(fld
262: .getDataType());
263: if (dt == null)
264: throw new Exception(
265: "Can't Translate Java Class "
266: + fld.getDataType()
267: + " to a supported Data Type");
268: kfld.setDataType(dt);
269: kfld
270: .setFieldNameInTargetComponent(reservedName(fld
271: .getName()));
272: }
273: }
274: }
275:
276: } catch (JAXBException e) {
277: log.error("Failed to create Lookup Object");
278: }
279: }
280:
281: /** Saves the generated meta data to the prespecified location as an XML file
282: * NOTE: assumes that the build(..) method has been called!
283: */
284: public boolean save() {
285: String filename = m_app.getOutputRoot()
286: + m_app.getOutputLookups() +
287: /* m_module.getName().toLowerCase() + File.separator +*/
288: m_domain.getDomainObject() + "Lookup.xml";
289: File file = new File(filename);
290: File path = new File(file.getParent());
291: if (!path.exists())
292: path.mkdirs();
293:
294: // Create output stream
295: FileOutputStream out = null;
296: try {
297: try {
298: out = new FileOutputStream(file.getPath());
299: } catch (FileNotFoundException e) {
300: log.error("Failed to open output stream !", e);
301: return false;
302: }
303:
304: try {
305: // create a JAXBContext capable of handling classes generated into the package
306: JAXBContext jc = JAXBContext
307: .newInstance("org.jaffa.patterns.library.object_lookup_meta_2_0.domain");
308: // create a Validator
309: Validator v = jc.createValidator();
310: ValidationEventCollector valErrors = new ValidationEventCollector();
311: v.setEventHandler(valErrors);
312: // validate the content tree
313: if (!v.validateRoot(m_lookup)) {
314: log.error("Failed to validate Structure !");
315: JAXBHelper.showErrors(log, valErrors);
316:
317: // Display current XML
318: ByteArrayOutputStream s = new ByteArrayOutputStream();
319: XMLEncoder e = new XMLEncoder(s);
320: e.writeObject(m_lookup);
321: e.close();
322: log
323: .error("Here is a XML representation of the invalid JavaBean...\n"
324: + s.toString());
325:
326: return false;
327: }
328:
329: // Write out XML document to file
330: Marshaller m = jc.createMarshaller();
331:
332: JAXBHelper
333: .marshalWithDocType(
334: m,
335: m_lookup,
336: out,
337: "Root",
338: "-//JAFFA//DTD Object Lookup Meta 2.0//EN",
339: "http://jaffa.sourceforge.net/DTD/object-lookup-meta_2_0.dtd");
340:
341: } catch (ValidationException e) {
342: log.error("Failed to validate Structure !", e);
343: return false;
344: } catch (JAXBException e) {
345: log
346: .error(
347: "Failed to marshal xml to output stream !",
348: e);
349: return false;
350: }
351: } finally {
352: if (out != null)
353: try {
354: out.close();
355: } catch (IOException e) {
356: }
357: }
358: return true;
359: }
360:
361: private static List reservedAttr = null;
362: static {
363: reservedAttr = new ArrayList();
364: reservedAttr.add("component");
365: }
366:
367: private String reservedName(String name) {
368: if (reservedAttr.contains(name.toLowerCase()))
369: return name + "1";
370: else
371: return name;
372: }
373:
374: public String getApplication() {
375: return m_lookup.getApplication();
376: }
377:
378: public String getComponentControllerClass() {
379: return m_lookup.getComponent() + "Component";
380: }
381:
382: public String getComponentControllerPackage() {
383: return m_lookup.getBasePackage() + ".components."
384: + m_lookup.getComponent().toLowerCase() + ".ui";
385: }
386:
387: public String getComponentName() {
388: return getModule() + "."
389: + StringHelper.getUpper1(m_lookup.getComponent());
390: }
391:
392: public String getComponentType() {
393: return "Lookup";
394: }
395:
396: public String getDomain() {
397: return m_lookup.getDomainPackage() + "."
398: + m_lookup.getDomainObject();
399: }
400:
401: public String getModule() {
402: return StringHelper.getUpper1(m_lookup.getModule());
403: }
404:
405: public String getName() {
406: return StringHelper.getUpper1(m_lookup.getComponent());
407: }
408:
409: /** Causes the meta data object to be build ready for saving.
410: * @param fullPackage If true then the .applications. and .modules. package names
411: * are used. If this is false, these are ommited for a much more condensed package
412: * naming convention
413: */
414: public void buildPhase2(boolean fullPackage) throws Exception {
415: ObjectFactory objFactory = new ObjectFactory();
416:
417: // Find The Viewer Component To Link To
418: IBuilder vcomp = m_compReg.findComponent(this .getDomain(),
419: "Viewer");
420: if (vcomp != null) {
421: Viewer viewer = objFactory.createViewer();
422: m_lookup.setViewer(viewer);
423: viewer.setClassName(vcomp.getComponentControllerClass());
424: viewer.setComponentName(vcomp.getComponentName());
425: viewer.setPackage(vcomp.getComponentControllerPackage());
426: }
427:
428: // Find The Maintenance Component To Link To
429: IBuilder mcomp = m_compReg.findComponent(this .getDomain(),
430: "Maintenance");
431: if (mcomp != null) {
432: // Updator
433: Updator updator = objFactory.createUpdator();
434: m_lookup.setUpdator(updator);
435: updator.setClassName(mcomp.getComponentControllerClass());
436: updator.setComponentName(mcomp.getComponentName());
437: updator.setPackage(mcomp.getComponentControllerPackage());
438: // Creator
439: Creator creator = objFactory.createCreator();
440: m_lookup.setCreator(creator);
441: creator.setClassName(mcomp.getComponentControllerClass());
442: creator.setComponentName(mcomp.getComponentName());
443: creator.setPackage(mcomp.getComponentControllerPackage());
444: // Creator
445: Deletor deletor = objFactory.createDeletor();
446: m_lookup.setDeletor(deletor);
447: deletor.setClassName(mcomp.getComponentControllerClass());
448: deletor.setComponentName(mcomp.getComponentName());
449: deletor.setPackage(mcomp.getComponentControllerPackage());
450: }
451:
452: }
453:
454: }
|